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