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