xref: /openbmc/linux/fs/smb/server/auth.c (revision 5a4c98323b01d52382575a7a4d6bf7bf5f326047)
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 "../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_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), 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 				  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 				  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, GFP_KERNEL);
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), GFP_KERNEL);
365 		if (!ctx_arc4)
366 			return -ENOMEM;
367 
368 		cifs_arc4_setkey(ctx_arc4, sess->sess_key,
369 				 SMB2_NTLMV2_SESSKEY_SIZE);
370 		cifs_arc4_crypt(ctx_arc4, sess->sess_key,
371 				(char *)authblob + sess_key_off, sess_key_len);
372 		kfree_sensitive(ctx_arc4);
373 	}
374 
375 	return ret;
376 }
377 
378 /**
379  * ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
380  * negotiate blob
381  * @negblob: negotiate blob source pointer
382  * @blob_len:	length of the @authblob message
383  * @conn:	connection
384  *
385  */
ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message * negblob,int blob_len,struct ksmbd_conn * conn)386 int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
387 				  int blob_len, struct ksmbd_conn *conn)
388 {
389 	if (blob_len < sizeof(struct negotiate_message)) {
390 		ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
391 			    blob_len);
392 		return -EINVAL;
393 	}
394 
395 	if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
396 		ksmbd_debug(AUTH, "blob signature incorrect %s\n",
397 			    negblob->Signature);
398 		return -EINVAL;
399 	}
400 
401 	conn->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
402 	return 0;
403 }
404 
405 /**
406  * ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
407  * challenge blob
408  * @chgblob: challenge blob source pointer to initialize
409  * @conn:	connection
410  *
411  */
412 unsigned int
ksmbd_build_ntlmssp_challenge_blob(struct challenge_message * chgblob,struct ksmbd_conn * conn)413 ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
414 				   struct ksmbd_conn *conn)
415 {
416 	struct target_info *tinfo;
417 	wchar_t *name;
418 	__u8 *target_name;
419 	unsigned int flags, blob_off, blob_len, type, target_info_len = 0;
420 	int len, uni_len, conv_len;
421 	int cflags = conn->ntlmssp.client_flags;
422 
423 	memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
424 	chgblob->MessageType = NtLmChallenge;
425 
426 	flags = NTLMSSP_NEGOTIATE_UNICODE |
427 		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
428 		NTLMSSP_NEGOTIATE_TARGET_INFO;
429 
430 	if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
431 		flags |= NTLMSSP_NEGOTIATE_SIGN;
432 		flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
433 				   NTLMSSP_NEGOTIATE_56);
434 	}
435 
436 	if (cflags & NTLMSSP_NEGOTIATE_SEAL && smb3_encryption_negotiated(conn))
437 		flags |= NTLMSSP_NEGOTIATE_SEAL;
438 
439 	if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
440 		flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
441 
442 	if (cflags & NTLMSSP_REQUEST_TARGET)
443 		flags |= NTLMSSP_REQUEST_TARGET;
444 
445 	if (conn->use_spnego &&
446 	    (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
447 		flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
448 
449 	if (cflags & NTLMSSP_NEGOTIATE_KEY_XCH)
450 		flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
451 
452 	chgblob->NegotiateFlags = cpu_to_le32(flags);
453 	len = strlen(ksmbd_netbios_name());
454 	name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
455 	if (!name)
456 		return -ENOMEM;
457 
458 	conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
459 				  conn->local_nls);
460 	if (conv_len < 0 || conv_len > len) {
461 		kfree(name);
462 		return -EINVAL;
463 	}
464 
465 	uni_len = UNICODE_LEN(conv_len);
466 
467 	blob_off = sizeof(struct challenge_message);
468 	blob_len = blob_off + uni_len;
469 
470 	chgblob->TargetName.Length = cpu_to_le16(uni_len);
471 	chgblob->TargetName.MaximumLength = cpu_to_le16(uni_len);
472 	chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
473 
474 	/* Initialize random conn challenge */
475 	get_random_bytes(conn->ntlmssp.cryptkey, sizeof(__u64));
476 	memcpy(chgblob->Challenge, conn->ntlmssp.cryptkey,
477 	       CIFS_CRYPTO_KEY_SIZE);
478 
479 	/* Add Target Information to security buffer */
480 	chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
481 
482 	target_name = (__u8 *)chgblob + blob_off;
483 	memcpy(target_name, name, uni_len);
484 	tinfo = (struct target_info *)(target_name + uni_len);
485 
486 	chgblob->TargetInfoArray.Length = 0;
487 	/* Add target info list for NetBIOS/DNS settings */
488 	for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
489 	     type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
490 		tinfo->Type = cpu_to_le16(type);
491 		tinfo->Length = cpu_to_le16(uni_len);
492 		memcpy(tinfo->Content, name, uni_len);
493 		tinfo = (struct target_info *)((char *)tinfo + 4 + uni_len);
494 		target_info_len += 4 + uni_len;
495 	}
496 
497 	/* Add terminator subblock */
498 	tinfo->Type = 0;
499 	tinfo->Length = 0;
500 	target_info_len += 4;
501 
502 	chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
503 	chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
504 	blob_len += target_info_len;
505 	kfree(name);
506 	ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
507 	return blob_len;
508 }
509 
510 #ifdef CONFIG_SMB_SERVER_KERBEROS5
ksmbd_krb5_authenticate(struct ksmbd_session * sess,char * in_blob,int in_len,char * out_blob,int * out_len)511 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
512 			    int in_len, char *out_blob, int *out_len)
513 {
514 	struct ksmbd_spnego_authen_response *resp;
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 	user = ksmbd_alloc_user(&resp->login_response);
544 	if (!user) {
545 		ksmbd_debug(AUTH, "login failure\n");
546 		retval = -ENOMEM;
547 		goto out;
548 	}
549 
550 	if (!sess->user) {
551 		/* First successful authentication */
552 		sess->user = user;
553 	} else {
554 		if (!ksmbd_compare_user(sess->user, user)) {
555 			ksmbd_debug(AUTH, "different user tried to reuse session\n");
556 			retval = -EPERM;
557 			ksmbd_free_user(user);
558 			goto out;
559 		}
560 		ksmbd_free_user(user);
561 	}
562 
563 	memcpy(sess->sess_key, resp->payload, resp->session_key_len);
564 	memcpy(out_blob, resp->payload + resp->session_key_len,
565 	       resp->spnego_blob_len);
566 	*out_len = resp->spnego_blob_len;
567 	retval = 0;
568 out:
569 	kvfree(resp);
570 	return retval;
571 }
572 #else
ksmbd_krb5_authenticate(struct ksmbd_session * sess,char * in_blob,int in_len,char * out_blob,int * out_len)573 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
574 			    int in_len, char *out_blob, int *out_len)
575 {
576 	return -EOPNOTSUPP;
577 }
578 #endif
579 
580 /**
581  * ksmbd_sign_smb2_pdu() - function to generate packet signing
582  * @conn:	connection
583  * @key:	signing key
584  * @iov:        buffer iov array
585  * @n_vec:	number of iovecs
586  * @sig:	signature value generated for client request packet
587  *
588  */
ksmbd_sign_smb2_pdu(struct ksmbd_conn * conn,char * key,struct kvec * iov,int n_vec,char * sig)589 int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
590 			int n_vec, char *sig)
591 {
592 	struct ksmbd_crypto_ctx *ctx;
593 	int rc, i;
594 
595 	ctx = ksmbd_crypto_ctx_find_hmacsha256();
596 	if (!ctx) {
597 		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
598 		return -ENOMEM;
599 	}
600 
601 	rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
602 				 key,
603 				 SMB2_NTLMV2_SESSKEY_SIZE);
604 	if (rc)
605 		goto out;
606 
607 	rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
608 	if (rc) {
609 		ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
610 		goto out;
611 	}
612 
613 	for (i = 0; i < n_vec; i++) {
614 		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
615 					 iov[i].iov_base,
616 					 iov[i].iov_len);
617 		if (rc) {
618 			ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
619 			goto out;
620 		}
621 	}
622 
623 	rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
624 	if (rc)
625 		ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
626 out:
627 	ksmbd_release_crypto_ctx(ctx);
628 	return rc;
629 }
630 
631 /**
632  * ksmbd_sign_smb3_pdu() - function to generate packet signing
633  * @conn:	connection
634  * @key:	signing key
635  * @iov:        buffer iov array
636  * @n_vec:	number of iovecs
637  * @sig:	signature value generated for client request packet
638  *
639  */
ksmbd_sign_smb3_pdu(struct ksmbd_conn * conn,char * key,struct kvec * iov,int n_vec,char * sig)640 int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
641 			int n_vec, char *sig)
642 {
643 	struct ksmbd_crypto_ctx *ctx;
644 	int rc, i;
645 
646 	ctx = ksmbd_crypto_ctx_find_cmacaes();
647 	if (!ctx) {
648 		ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
649 		return -ENOMEM;
650 	}
651 
652 	rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
653 				 key,
654 				 SMB2_CMACAES_SIZE);
655 	if (rc)
656 		goto out;
657 
658 	rc = crypto_shash_init(CRYPTO_CMACAES(ctx));
659 	if (rc) {
660 		ksmbd_debug(AUTH, "cmaces init error %d\n", rc);
661 		goto out;
662 	}
663 
664 	for (i = 0; i < n_vec; i++) {
665 		rc = crypto_shash_update(CRYPTO_CMACAES(ctx),
666 					 iov[i].iov_base,
667 					 iov[i].iov_len);
668 		if (rc) {
669 			ksmbd_debug(AUTH, "cmaces update error %d\n", rc);
670 			goto out;
671 		}
672 	}
673 
674 	rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig);
675 	if (rc)
676 		ksmbd_debug(AUTH, "cmaces generation error %d\n", rc);
677 out:
678 	ksmbd_release_crypto_ctx(ctx);
679 	return rc;
680 }
681 
682 struct derivation {
683 	struct kvec label;
684 	struct kvec context;
685 	bool binding;
686 };
687 
generate_key(struct ksmbd_conn * conn,struct ksmbd_session * sess,struct kvec label,struct kvec context,__u8 * key,unsigned int key_size)688 static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
689 			struct kvec label, struct kvec context, __u8 *key,
690 			unsigned int key_size)
691 {
692 	unsigned char zero = 0x0;
693 	__u8 i[4] = {0, 0, 0, 1};
694 	__u8 L128[4] = {0, 0, 0, 128};
695 	__u8 L256[4] = {0, 0, 1, 0};
696 	int rc;
697 	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
698 	unsigned char *hashptr = prfhash;
699 	struct ksmbd_crypto_ctx *ctx;
700 
701 	memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
702 	memset(key, 0x0, key_size);
703 
704 	ctx = ksmbd_crypto_ctx_find_hmacsha256();
705 	if (!ctx) {
706 		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
707 		return -ENOMEM;
708 	}
709 
710 	rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
711 				 sess->sess_key,
712 				 SMB2_NTLMV2_SESSKEY_SIZE);
713 	if (rc)
714 		goto smb3signkey_ret;
715 
716 	rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
717 	if (rc) {
718 		ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
719 		goto smb3signkey_ret;
720 	}
721 
722 	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
723 	if (rc) {
724 		ksmbd_debug(AUTH, "could not update with n\n");
725 		goto smb3signkey_ret;
726 	}
727 
728 	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
729 				 label.iov_base,
730 				 label.iov_len);
731 	if (rc) {
732 		ksmbd_debug(AUTH, "could not update with label\n");
733 		goto smb3signkey_ret;
734 	}
735 
736 	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
737 	if (rc) {
738 		ksmbd_debug(AUTH, "could not update with zero\n");
739 		goto smb3signkey_ret;
740 	}
741 
742 	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
743 				 context.iov_base,
744 				 context.iov_len);
745 	if (rc) {
746 		ksmbd_debug(AUTH, "could not update with context\n");
747 		goto smb3signkey_ret;
748 	}
749 
750 	if (key_size == SMB3_ENC_DEC_KEY_SIZE &&
751 	    (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
752 	     conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
753 		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
754 	else
755 		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
756 	if (rc) {
757 		ksmbd_debug(AUTH, "could not update with L\n");
758 		goto smb3signkey_ret;
759 	}
760 
761 	rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
762 	if (rc) {
763 		ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
764 			    rc);
765 		goto smb3signkey_ret;
766 	}
767 
768 	memcpy(key, hashptr, key_size);
769 
770 smb3signkey_ret:
771 	ksmbd_release_crypto_ctx(ctx);
772 	return rc;
773 }
774 
generate_smb3signingkey(struct ksmbd_session * sess,struct ksmbd_conn * conn,const struct derivation * signing)775 static int generate_smb3signingkey(struct ksmbd_session *sess,
776 				   struct ksmbd_conn *conn,
777 				   const struct derivation *signing)
778 {
779 	int rc;
780 	struct channel *chann;
781 	char *key;
782 
783 	chann = lookup_chann_list(sess, conn);
784 	if (!chann)
785 		return 0;
786 
787 	if (conn->dialect >= SMB30_PROT_ID && signing->binding)
788 		key = chann->smb3signingkey;
789 	else
790 		key = sess->smb3signingkey;
791 
792 	rc = generate_key(conn, sess, signing->label, signing->context, key,
793 			  SMB3_SIGN_KEY_SIZE);
794 	if (rc)
795 		return rc;
796 
797 	if (!(conn->dialect >= SMB30_PROT_ID && signing->binding))
798 		memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
799 
800 	ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
801 	ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
802 	ksmbd_debug(AUTH, "Session Key   %*ph\n",
803 		    SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
804 	ksmbd_debug(AUTH, "Signing Key   %*ph\n",
805 		    SMB3_SIGN_KEY_SIZE, key);
806 	return 0;
807 }
808 
ksmbd_gen_smb30_signingkey(struct ksmbd_session * sess,struct ksmbd_conn * conn)809 int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
810 			       struct ksmbd_conn *conn)
811 {
812 	struct derivation d;
813 
814 	d.label.iov_base = "SMB2AESCMAC";
815 	d.label.iov_len = 12;
816 	d.context.iov_base = "SmbSign";
817 	d.context.iov_len = 8;
818 	d.binding = conn->binding;
819 
820 	return generate_smb3signingkey(sess, conn, &d);
821 }
822 
ksmbd_gen_smb311_signingkey(struct ksmbd_session * sess,struct ksmbd_conn * conn)823 int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
824 				struct ksmbd_conn *conn)
825 {
826 	struct derivation d;
827 
828 	d.label.iov_base = "SMBSigningKey";
829 	d.label.iov_len = 14;
830 	if (conn->binding) {
831 		struct preauth_session *preauth_sess;
832 
833 		preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
834 		if (!preauth_sess)
835 			return -ENOENT;
836 		d.context.iov_base = preauth_sess->Preauth_HashValue;
837 	} else {
838 		d.context.iov_base = sess->Preauth_HashValue;
839 	}
840 	d.context.iov_len = 64;
841 	d.binding = conn->binding;
842 
843 	return generate_smb3signingkey(sess, conn, &d);
844 }
845 
846 struct derivation_twin {
847 	struct derivation encryption;
848 	struct derivation decryption;
849 };
850 
generate_smb3encryptionkey(struct ksmbd_conn * conn,struct ksmbd_session * sess,const struct derivation_twin * ptwin)851 static int generate_smb3encryptionkey(struct ksmbd_conn *conn,
852 				      struct ksmbd_session *sess,
853 				      const struct derivation_twin *ptwin)
854 {
855 	int rc;
856 
857 	rc = generate_key(conn, sess, ptwin->encryption.label,
858 			  ptwin->encryption.context, sess->smb3encryptionkey,
859 			  SMB3_ENC_DEC_KEY_SIZE);
860 	if (rc)
861 		return rc;
862 
863 	rc = generate_key(conn, sess, ptwin->decryption.label,
864 			  ptwin->decryption.context,
865 			  sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
866 	if (rc)
867 		return rc;
868 
869 	ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
870 	ksmbd_debug(AUTH, "Cipher type   %d\n", conn->cipher_type);
871 	ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
872 	ksmbd_debug(AUTH, "Session Key   %*ph\n",
873 		    SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
874 	if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
875 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
876 		ksmbd_debug(AUTH, "ServerIn Key  %*ph\n",
877 			    SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
878 		ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
879 			    SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
880 	} else {
881 		ksmbd_debug(AUTH, "ServerIn Key  %*ph\n",
882 			    SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
883 		ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
884 			    SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
885 	}
886 	return 0;
887 }
888 
ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn * conn,struct ksmbd_session * sess)889 int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
890 				  struct ksmbd_session *sess)
891 {
892 	struct derivation_twin twin;
893 	struct derivation *d;
894 
895 	d = &twin.encryption;
896 	d->label.iov_base = "SMB2AESCCM";
897 	d->label.iov_len = 11;
898 	d->context.iov_base = "ServerOut";
899 	d->context.iov_len = 10;
900 
901 	d = &twin.decryption;
902 	d->label.iov_base = "SMB2AESCCM";
903 	d->label.iov_len = 11;
904 	d->context.iov_base = "ServerIn ";
905 	d->context.iov_len = 10;
906 
907 	return generate_smb3encryptionkey(conn, sess, &twin);
908 }
909 
ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn * conn,struct ksmbd_session * sess)910 int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
911 				   struct ksmbd_session *sess)
912 {
913 	struct derivation_twin twin;
914 	struct derivation *d;
915 
916 	d = &twin.encryption;
917 	d->label.iov_base = "SMBS2CCipherKey";
918 	d->label.iov_len = 16;
919 	d->context.iov_base = sess->Preauth_HashValue;
920 	d->context.iov_len = 64;
921 
922 	d = &twin.decryption;
923 	d->label.iov_base = "SMBC2SCipherKey";
924 	d->label.iov_len = 16;
925 	d->context.iov_base = sess->Preauth_HashValue;
926 	d->context.iov_len = 64;
927 
928 	return generate_smb3encryptionkey(conn, sess, &twin);
929 }
930 
ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn * conn,char * buf,__u8 * pi_hash)931 int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
932 				     __u8 *pi_hash)
933 {
934 	int rc;
935 	struct smb2_hdr *rcv_hdr = smb2_get_msg(buf);
936 	char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
937 	int msg_size = get_rfc1002_len(buf);
938 	struct ksmbd_crypto_ctx *ctx = NULL;
939 
940 	if (conn->preauth_info->Preauth_HashId !=
941 	    SMB2_PREAUTH_INTEGRITY_SHA512)
942 		return -EINVAL;
943 
944 	ctx = ksmbd_crypto_ctx_find_sha512();
945 	if (!ctx) {
946 		ksmbd_debug(AUTH, "could not alloc sha512\n");
947 		return -ENOMEM;
948 	}
949 
950 	rc = crypto_shash_init(CRYPTO_SHA512(ctx));
951 	if (rc) {
952 		ksmbd_debug(AUTH, "could not init shashn");
953 		goto out;
954 	}
955 
956 	rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
957 	if (rc) {
958 		ksmbd_debug(AUTH, "could not update with n\n");
959 		goto out;
960 	}
961 
962 	rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
963 	if (rc) {
964 		ksmbd_debug(AUTH, "could not update with n\n");
965 		goto out;
966 	}
967 
968 	rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
969 	if (rc) {
970 		ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
971 		goto out;
972 	}
973 out:
974 	ksmbd_release_crypto_ctx(ctx);
975 	return rc;
976 }
977 
ksmbd_gen_sd_hash(struct ksmbd_conn * conn,char * sd_buf,int len,__u8 * pi_hash)978 int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
979 		      __u8 *pi_hash)
980 {
981 	int rc;
982 	struct ksmbd_crypto_ctx *ctx = NULL;
983 
984 	ctx = ksmbd_crypto_ctx_find_sha256();
985 	if (!ctx) {
986 		ksmbd_debug(AUTH, "could not alloc sha256\n");
987 		return -ENOMEM;
988 	}
989 
990 	rc = crypto_shash_init(CRYPTO_SHA256(ctx));
991 	if (rc) {
992 		ksmbd_debug(AUTH, "could not init shashn");
993 		goto out;
994 	}
995 
996 	rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
997 	if (rc) {
998 		ksmbd_debug(AUTH, "could not update with n\n");
999 		goto out;
1000 	}
1001 
1002 	rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
1003 	if (rc) {
1004 		ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
1005 		goto out;
1006 	}
1007 out:
1008 	ksmbd_release_crypto_ctx(ctx);
1009 	return rc;
1010 }
1011 
ksmbd_get_encryption_key(struct ksmbd_work * work,__u64 ses_id,int enc,u8 * key)1012 static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id,
1013 				    int enc, u8 *key)
1014 {
1015 	struct ksmbd_session *sess;
1016 	u8 *ses_enc_key;
1017 
1018 	if (enc)
1019 		sess = work->sess;
1020 	else
1021 		sess = ksmbd_session_lookup_all(work->conn, ses_id);
1022 	if (!sess)
1023 		return -EINVAL;
1024 
1025 	ses_enc_key = enc ? sess->smb3encryptionkey :
1026 		sess->smb3decryptionkey;
1027 	memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
1028 	if (!enc)
1029 		ksmbd_user_session_put(sess);
1030 
1031 	return 0;
1032 }
1033 
smb2_sg_set_buf(struct scatterlist * sg,const void * buf,unsigned int buflen)1034 static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
1035 				   unsigned int buflen)
1036 {
1037 	void *addr;
1038 
1039 	if (is_vmalloc_addr(buf))
1040 		addr = vmalloc_to_page(buf);
1041 	else
1042 		addr = virt_to_page(buf);
1043 	sg_set_page(sg, addr, buflen, offset_in_page(buf));
1044 }
1045 
ksmbd_init_sg(struct kvec * iov,unsigned int nvec,u8 * sign)1046 static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
1047 					 u8 *sign)
1048 {
1049 	struct scatterlist *sg;
1050 	unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1051 	int i, *nr_entries, total_entries = 0, sg_idx = 0;
1052 
1053 	if (!nvec)
1054 		return NULL;
1055 
1056 	nr_entries = kcalloc(nvec, sizeof(int), GFP_KERNEL);
1057 	if (!nr_entries)
1058 		return NULL;
1059 
1060 	for (i = 0; i < nvec - 1; i++) {
1061 		unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
1062 
1063 		if (is_vmalloc_addr(iov[i + 1].iov_base)) {
1064 			nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
1065 					PAGE_SIZE - 1) >> PAGE_SHIFT) -
1066 				(kaddr >> PAGE_SHIFT);
1067 		} else {
1068 			nr_entries[i]++;
1069 		}
1070 		total_entries += nr_entries[i];
1071 	}
1072 
1073 	/* Add two entries for transform header and signature */
1074 	total_entries += 2;
1075 
1076 	sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
1077 	if (!sg) {
1078 		kfree(nr_entries);
1079 		return NULL;
1080 	}
1081 
1082 	sg_init_table(sg, total_entries);
1083 	smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1084 	for (i = 0; i < nvec - 1; i++) {
1085 		void *data = iov[i + 1].iov_base;
1086 		int len = iov[i + 1].iov_len;
1087 
1088 		if (is_vmalloc_addr(data)) {
1089 			int j, offset = offset_in_page(data);
1090 
1091 			for (j = 0; j < nr_entries[i]; j++) {
1092 				unsigned int bytes = PAGE_SIZE - offset;
1093 
1094 				if (!len)
1095 					break;
1096 
1097 				if (bytes > len)
1098 					bytes = len;
1099 
1100 				sg_set_page(&sg[sg_idx++],
1101 					    vmalloc_to_page(data), bytes,
1102 					    offset_in_page(data));
1103 
1104 				data += bytes;
1105 				len -= bytes;
1106 				offset = 0;
1107 			}
1108 		} else {
1109 			sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1110 				    offset_in_page(data));
1111 		}
1112 	}
1113 	smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1114 	kfree(nr_entries);
1115 	return sg;
1116 }
1117 
ksmbd_crypt_message(struct ksmbd_work * work,struct kvec * iov,unsigned int nvec,int enc)1118 int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
1119 			unsigned int nvec, int enc)
1120 {
1121 	struct ksmbd_conn *conn = work->conn;
1122 	struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
1123 	unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1124 	int rc;
1125 	struct scatterlist *sg;
1126 	u8 sign[SMB2_SIGNATURE_SIZE] = {};
1127 	u8 key[SMB3_ENC_DEC_KEY_SIZE];
1128 	struct aead_request *req;
1129 	char *iv;
1130 	unsigned int iv_len;
1131 	struct crypto_aead *tfm;
1132 	unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1133 	struct ksmbd_crypto_ctx *ctx;
1134 
1135 	rc = ksmbd_get_encryption_key(work,
1136 				      le64_to_cpu(tr_hdr->SessionId),
1137 				      enc,
1138 				      key);
1139 	if (rc) {
1140 		pr_err("Could not get %scryption key\n", enc ? "en" : "de");
1141 		return rc;
1142 	}
1143 
1144 	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1145 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1146 		ctx = ksmbd_crypto_ctx_find_gcm();
1147 	else
1148 		ctx = ksmbd_crypto_ctx_find_ccm();
1149 	if (!ctx) {
1150 		pr_err("crypto alloc failed\n");
1151 		return -ENOMEM;
1152 	}
1153 
1154 	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1155 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1156 		tfm = CRYPTO_GCM(ctx);
1157 	else
1158 		tfm = CRYPTO_CCM(ctx);
1159 
1160 	if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1161 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1162 		rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1163 	else
1164 		rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
1165 	if (rc) {
1166 		pr_err("Failed to set aead key %d\n", rc);
1167 		goto free_ctx;
1168 	}
1169 
1170 	rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1171 	if (rc) {
1172 		pr_err("Failed to set authsize %d\n", rc);
1173 		goto free_ctx;
1174 	}
1175 
1176 	req = aead_request_alloc(tfm, GFP_KERNEL);
1177 	if (!req) {
1178 		rc = -ENOMEM;
1179 		goto free_ctx;
1180 	}
1181 
1182 	if (!enc) {
1183 		memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1184 		crypt_len += SMB2_SIGNATURE_SIZE;
1185 	}
1186 
1187 	sg = ksmbd_init_sg(iov, nvec, sign);
1188 	if (!sg) {
1189 		pr_err("Failed to init sg\n");
1190 		rc = -ENOMEM;
1191 		goto free_req;
1192 	}
1193 
1194 	iv_len = crypto_aead_ivsize(tfm);
1195 	iv = kzalloc(iv_len, GFP_KERNEL);
1196 	if (!iv) {
1197 		rc = -ENOMEM;
1198 		goto free_sg;
1199 	}
1200 
1201 	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1202 	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1203 		memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
1204 	} else {
1205 		iv[0] = 3;
1206 		memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
1207 	}
1208 
1209 	aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1210 	aead_request_set_ad(req, assoc_data_len);
1211 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1212 
1213 	if (enc)
1214 		rc = crypto_aead_encrypt(req);
1215 	else
1216 		rc = crypto_aead_decrypt(req);
1217 	if (rc)
1218 		goto free_iv;
1219 
1220 	if (enc)
1221 		memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1222 
1223 free_iv:
1224 	kfree(iv);
1225 free_sg:
1226 	kfree(sg);
1227 free_req:
1228 	aead_request_free(req);
1229 free_ctx:
1230 	ksmbd_release_crypto_ctx(ctx);
1231 	return rc;
1232 }
1233