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