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