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