Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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 ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL);
359 if (!ctx_arc4)
360 return -ENOMEM;
361
362 cifs_arc4_setkey(ctx_arc4, sess->sess_key,
363 SMB2_NTLMV2_SESSKEY_SIZE);
364 cifs_arc4_crypt(ctx_arc4, sess->sess_key,
365 (char *)authblob + sess_key_off, sess_key_len);
366 kfree_sensitive(ctx_arc4);
367 }
368
369 return ret;
370}
371
372/**
373 * ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
374 * negotiate blob
375 * @negblob: negotiate blob source pointer
376 * @rsp: response header pointer to be updated
377 * @sess: session of connection
378 *
379 */
380int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
381 int blob_len, struct ksmbd_conn *conn)
382{
383 if (blob_len < sizeof(struct negotiate_message)) {
384 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
385 blob_len);
386 return -EINVAL;
387 }
388
389 if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
390 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
391 negblob->Signature);
392 return -EINVAL;
393 }
394
395 conn->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
396 return 0;
397}
398
399/**
400 * ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
401 * challenge blob
402 * @chgblob: challenge blob source pointer to initialize
403 * @rsp: response header pointer to be updated
404 * @sess: session of connection
405 *
406 */
407unsigned int
408ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
409 struct ksmbd_conn *conn)
410{
411 struct target_info *tinfo;
412 wchar_t *name;
413 __u8 *target_name;
414 unsigned int flags, blob_off, blob_len, type, target_info_len = 0;
415 int len, uni_len, conv_len;
416 int cflags = conn->ntlmssp.client_flags;
417
418 memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
419 chgblob->MessageType = NtLmChallenge;
420
421 flags = NTLMSSP_NEGOTIATE_UNICODE |
422 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
423 NTLMSSP_NEGOTIATE_TARGET_INFO;
424
425 if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
426 flags |= NTLMSSP_NEGOTIATE_SIGN;
427 flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
428 NTLMSSP_NEGOTIATE_56);
429 }
430
431 if (cflags & NTLMSSP_NEGOTIATE_SEAL && smb3_encryption_negotiated(conn))
432 flags |= NTLMSSP_NEGOTIATE_SEAL;
433
434 if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
435 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
436
437 if (cflags & NTLMSSP_REQUEST_TARGET)
438 flags |= NTLMSSP_REQUEST_TARGET;
439
440 if (conn->use_spnego &&
441 (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
442 flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
443
444 if (cflags & NTLMSSP_NEGOTIATE_KEY_XCH)
445 flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
446
447 chgblob->NegotiateFlags = cpu_to_le32(flags);
448 len = strlen(ksmbd_netbios_name());
449 name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
450 if (!name)
451 return -ENOMEM;
452
453 conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
454 conn->local_nls);
455 if (conv_len < 0 || conv_len > len) {
456 kfree(name);
457 return -EINVAL;
458 }
459
460 uni_len = UNICODE_LEN(conv_len);
461
462 blob_off = sizeof(struct challenge_message);
463 blob_len = blob_off + uni_len;
464
465 chgblob->TargetName.Length = cpu_to_le16(uni_len);
466 chgblob->TargetName.MaximumLength = cpu_to_le16(uni_len);
467 chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
468
469 /* Initialize random conn challenge */
470 get_random_bytes(conn->ntlmssp.cryptkey, sizeof(__u64));
471 memcpy(chgblob->Challenge, conn->ntlmssp.cryptkey,
472 CIFS_CRYPTO_KEY_SIZE);
473
474 /* Add Target Information to security buffer */
475 chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
476
477 target_name = (__u8 *)chgblob + blob_off;
478 memcpy(target_name, name, uni_len);
479 tinfo = (struct target_info *)(target_name + uni_len);
480
481 chgblob->TargetInfoArray.Length = 0;
482 /* Add target info list for NetBIOS/DNS settings */
483 for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
484 type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
485 tinfo->Type = cpu_to_le16(type);
486 tinfo->Length = cpu_to_le16(uni_len);
487 memcpy(tinfo->Content, name, uni_len);
488 tinfo = (struct target_info *)((char *)tinfo + 4 + uni_len);
489 target_info_len += 4 + uni_len;
490 }
491
492 /* Add terminator subblock */
493 tinfo->Type = 0;
494 tinfo->Length = 0;
495 target_info_len += 4;
496
497 chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
498 chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
499 blob_len += target_info_len;
500 kfree(name);
501 ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
502 return blob_len;
503}
504
505#ifdef CONFIG_SMB_SERVER_KERBEROS5
506int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
507 int in_len, char *out_blob, int *out_len)
508{
509 struct ksmbd_spnego_authen_response *resp;
510 struct ksmbd_user *user = NULL;
511 int retval;
512
513 resp = ksmbd_ipc_spnego_authen_request(in_blob, in_len);
514 if (!resp) {
515 ksmbd_debug(AUTH, "SPNEGO_AUTHEN_REQUEST failure\n");
516 return -EINVAL;
517 }
518
519 if (!(resp->login_response.status & KSMBD_USER_FLAG_OK)) {
520 ksmbd_debug(AUTH, "krb5 authentication failure\n");
521 retval = -EPERM;
522 goto out;
523 }
524
525 if (*out_len <= resp->spnego_blob_len) {
526 ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
527 *out_len, resp->spnego_blob_len);
528 retval = -EINVAL;
529 goto out;
530 }
531
532 if (resp->session_key_len > sizeof(sess->sess_key)) {
533 ksmbd_debug(AUTH, "session key is too long\n");
534 retval = -EINVAL;
535 goto out;
536 }
537
538 user = ksmbd_alloc_user(&resp->login_response);
539 if (!user) {
540 ksmbd_debug(AUTH, "login failure\n");
541 retval = -ENOMEM;
542 goto out;
543 }
544 sess->user = user;
545
546 memcpy(sess->sess_key, resp->payload, resp->session_key_len);
547 memcpy(out_blob, resp->payload + resp->session_key_len,
548 resp->spnego_blob_len);
549 *out_len = resp->spnego_blob_len;
550 retval = 0;
551out:
552 kvfree(resp);
553 return retval;
554}
555#else
556int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
557 int in_len, char *out_blob, int *out_len)
558{
559 return -EOPNOTSUPP;
560}
561#endif
562
563/**
564 * ksmbd_sign_smb2_pdu() - function to generate packet signing
565 * @conn: connection
566 * @key: signing key
567 * @iov: buffer iov array
568 * @n_vec: number of iovecs
569 * @sig: signature value generated for client request packet
570 *
571 */
572int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
573 int n_vec, char *sig)
574{
575 struct ksmbd_crypto_ctx *ctx;
576 int rc, i;
577
578 ctx = ksmbd_crypto_ctx_find_hmacsha256();
579 if (!ctx) {
580 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
581 return -ENOMEM;
582 }
583
584 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
585 key,
586 SMB2_NTLMV2_SESSKEY_SIZE);
587 if (rc)
588 goto out;
589
590 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
591 if (rc) {
592 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
593 goto out;
594 }
595
596 for (i = 0; i < n_vec; i++) {
597 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
598 iov[i].iov_base,
599 iov[i].iov_len);
600 if (rc) {
601 ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
602 goto out;
603 }
604 }
605
606 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
607 if (rc)
608 ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
609out:
610 ksmbd_release_crypto_ctx(ctx);
611 return rc;
612}
613
614/**
615 * ksmbd_sign_smb3_pdu() - function to generate packet signing
616 * @conn: connection
617 * @key: signing key
618 * @iov: buffer iov array
619 * @n_vec: number of iovecs
620 * @sig: signature value generated for client request packet
621 *
622 */
623int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
624 int n_vec, char *sig)
625{
626 struct ksmbd_crypto_ctx *ctx;
627 int rc, i;
628
629 ctx = ksmbd_crypto_ctx_find_cmacaes();
630 if (!ctx) {
631 ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
632 return -ENOMEM;
633 }
634
635 rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
636 key,
637 SMB2_CMACAES_SIZE);
638 if (rc)
639 goto out;
640
641 rc = crypto_shash_init(CRYPTO_CMACAES(ctx));
642 if (rc) {
643 ksmbd_debug(AUTH, "cmaces init error %d\n", rc);
644 goto out;
645 }
646
647 for (i = 0; i < n_vec; i++) {
648 rc = crypto_shash_update(CRYPTO_CMACAES(ctx),
649 iov[i].iov_base,
650 iov[i].iov_len);
651 if (rc) {
652 ksmbd_debug(AUTH, "cmaces update error %d\n", rc);
653 goto out;
654 }
655 }
656
657 rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig);
658 if (rc)
659 ksmbd_debug(AUTH, "cmaces generation error %d\n", rc);
660out:
661 ksmbd_release_crypto_ctx(ctx);
662 return rc;
663}
664
665struct derivation {
666 struct kvec label;
667 struct kvec context;
668 bool binding;
669};
670
671static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
672 struct kvec label, struct kvec context, __u8 *key,
673 unsigned int key_size)
674{
675 unsigned char zero = 0x0;
676 __u8 i[4] = {0, 0, 0, 1};
677 __u8 L128[4] = {0, 0, 0, 128};
678 __u8 L256[4] = {0, 0, 1, 0};
679 int rc;
680 unsigned char prfhash[SMB2_HMACSHA256_SIZE];
681 unsigned char *hashptr = prfhash;
682 struct ksmbd_crypto_ctx *ctx;
683
684 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
685 memset(key, 0x0, key_size);
686
687 ctx = ksmbd_crypto_ctx_find_hmacsha256();
688 if (!ctx) {
689 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
690 return -ENOMEM;
691 }
692
693 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
694 sess->sess_key,
695 SMB2_NTLMV2_SESSKEY_SIZE);
696 if (rc)
697 goto smb3signkey_ret;
698
699 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
700 if (rc) {
701 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
702 goto smb3signkey_ret;
703 }
704
705 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
706 if (rc) {
707 ksmbd_debug(AUTH, "could not update with n\n");
708 goto smb3signkey_ret;
709 }
710
711 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
712 label.iov_base,
713 label.iov_len);
714 if (rc) {
715 ksmbd_debug(AUTH, "could not update with label\n");
716 goto smb3signkey_ret;
717 }
718
719 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
720 if (rc) {
721 ksmbd_debug(AUTH, "could not update with zero\n");
722 goto smb3signkey_ret;
723 }
724
725 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
726 context.iov_base,
727 context.iov_len);
728 if (rc) {
729 ksmbd_debug(AUTH, "could not update with context\n");
730 goto smb3signkey_ret;
731 }
732
733 if (key_size == SMB3_ENC_DEC_KEY_SIZE &&
734 (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
735 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
736 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
737 else
738 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
739 if (rc) {
740 ksmbd_debug(AUTH, "could not update with L\n");
741 goto smb3signkey_ret;
742 }
743
744 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
745 if (rc) {
746 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
747 rc);
748 goto smb3signkey_ret;
749 }
750
751 memcpy(key, hashptr, key_size);
752
753smb3signkey_ret:
754 ksmbd_release_crypto_ctx(ctx);
755 return rc;
756}
757
758static int generate_smb3signingkey(struct ksmbd_session *sess,
759 struct ksmbd_conn *conn,
760 const struct derivation *signing)
761{
762 int rc;
763 struct channel *chann;
764 char *key;
765
766 chann = lookup_chann_list(sess, conn);
767 if (!chann)
768 return 0;
769
770 if (conn->dialect >= SMB30_PROT_ID && signing->binding)
771 key = chann->smb3signingkey;
772 else
773 key = sess->smb3signingkey;
774
775 rc = generate_key(conn, sess, signing->label, signing->context, key,
776 SMB3_SIGN_KEY_SIZE);
777 if (rc)
778 return rc;
779
780 if (!(conn->dialect >= SMB30_PROT_ID && signing->binding))
781 memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
782
783 ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
784 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
785 ksmbd_debug(AUTH, "Session Key %*ph\n",
786 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
787 ksmbd_debug(AUTH, "Signing Key %*ph\n",
788 SMB3_SIGN_KEY_SIZE, key);
789 return 0;
790}
791
792int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
793 struct ksmbd_conn *conn)
794{
795 struct derivation d;
796
797 d.label.iov_base = "SMB2AESCMAC";
798 d.label.iov_len = 12;
799 d.context.iov_base = "SmbSign";
800 d.context.iov_len = 8;
801 d.binding = conn->binding;
802
803 return generate_smb3signingkey(sess, conn, &d);
804}
805
806int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
807 struct ksmbd_conn *conn)
808{
809 struct derivation d;
810
811 d.label.iov_base = "SMBSigningKey";
812 d.label.iov_len = 14;
813 if (conn->binding) {
814 struct preauth_session *preauth_sess;
815
816 preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
817 if (!preauth_sess)
818 return -ENOENT;
819 d.context.iov_base = preauth_sess->Preauth_HashValue;
820 } else {
821 d.context.iov_base = sess->Preauth_HashValue;
822 }
823 d.context.iov_len = 64;
824 d.binding = conn->binding;
825
826 return generate_smb3signingkey(sess, conn, &d);
827}
828
829struct derivation_twin {
830 struct derivation encryption;
831 struct derivation decryption;
832};
833
834static int generate_smb3encryptionkey(struct ksmbd_conn *conn,
835 struct ksmbd_session *sess,
836 const struct derivation_twin *ptwin)
837{
838 int rc;
839
840 rc = generate_key(conn, sess, ptwin->encryption.label,
841 ptwin->encryption.context, sess->smb3encryptionkey,
842 SMB3_ENC_DEC_KEY_SIZE);
843 if (rc)
844 return rc;
845
846 rc = generate_key(conn, sess, ptwin->decryption.label,
847 ptwin->decryption.context,
848 sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
849 if (rc)
850 return rc;
851
852 ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
853 ksmbd_debug(AUTH, "Cipher type %d\n", conn->cipher_type);
854 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
855 ksmbd_debug(AUTH, "Session Key %*ph\n",
856 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
857 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
858 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
859 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
860 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
861 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
862 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
863 } else {
864 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
865 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
866 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
867 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
868 }
869 return 0;
870}
871
872int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
873 struct ksmbd_session *sess)
874{
875 struct derivation_twin twin;
876 struct derivation *d;
877
878 d = &twin.encryption;
879 d->label.iov_base = "SMB2AESCCM";
880 d->label.iov_len = 11;
881 d->context.iov_base = "ServerOut";
882 d->context.iov_len = 10;
883
884 d = &twin.decryption;
885 d->label.iov_base = "SMB2AESCCM";
886 d->label.iov_len = 11;
887 d->context.iov_base = "ServerIn ";
888 d->context.iov_len = 10;
889
890 return generate_smb3encryptionkey(conn, sess, &twin);
891}
892
893int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
894 struct ksmbd_session *sess)
895{
896 struct derivation_twin twin;
897 struct derivation *d;
898
899 d = &twin.encryption;
900 d->label.iov_base = "SMBS2CCipherKey";
901 d->label.iov_len = 16;
902 d->context.iov_base = sess->Preauth_HashValue;
903 d->context.iov_len = 64;
904
905 d = &twin.decryption;
906 d->label.iov_base = "SMBC2SCipherKey";
907 d->label.iov_len = 16;
908 d->context.iov_base = sess->Preauth_HashValue;
909 d->context.iov_len = 64;
910
911 return generate_smb3encryptionkey(conn, sess, &twin);
912}
913
914int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
915 __u8 *pi_hash)
916{
917 int rc;
918 struct smb2_hdr *rcv_hdr = smb2_get_msg(buf);
919 char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
920 int msg_size = get_rfc1002_len(buf);
921 struct ksmbd_crypto_ctx *ctx = NULL;
922
923 if (conn->preauth_info->Preauth_HashId !=
924 SMB2_PREAUTH_INTEGRITY_SHA512)
925 return -EINVAL;
926
927 ctx = ksmbd_crypto_ctx_find_sha512();
928 if (!ctx) {
929 ksmbd_debug(AUTH, "could not alloc sha512\n");
930 return -ENOMEM;
931 }
932
933 rc = crypto_shash_init(CRYPTO_SHA512(ctx));
934 if (rc) {
935 ksmbd_debug(AUTH, "could not init shashn");
936 goto out;
937 }
938
939 rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
940 if (rc) {
941 ksmbd_debug(AUTH, "could not update with n\n");
942 goto out;
943 }
944
945 rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
946 if (rc) {
947 ksmbd_debug(AUTH, "could not update with n\n");
948 goto out;
949 }
950
951 rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
952 if (rc) {
953 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
954 goto out;
955 }
956out:
957 ksmbd_release_crypto_ctx(ctx);
958 return rc;
959}
960
961int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
962 __u8 *pi_hash)
963{
964 int rc;
965 struct ksmbd_crypto_ctx *ctx = NULL;
966
967 ctx = ksmbd_crypto_ctx_find_sha256();
968 if (!ctx) {
969 ksmbd_debug(AUTH, "could not alloc sha256\n");
970 return -ENOMEM;
971 }
972
973 rc = crypto_shash_init(CRYPTO_SHA256(ctx));
974 if (rc) {
975 ksmbd_debug(AUTH, "could not init shashn");
976 goto out;
977 }
978
979 rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
980 if (rc) {
981 ksmbd_debug(AUTH, "could not update with n\n");
982 goto out;
983 }
984
985 rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
986 if (rc) {
987 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
988 goto out;
989 }
990out:
991 ksmbd_release_crypto_ctx(ctx);
992 return rc;
993}
994
995static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id,
996 int enc, u8 *key)
997{
998 struct ksmbd_session *sess;
999 u8 *ses_enc_key;
1000
1001 if (enc)
1002 sess = work->sess;
1003 else
1004 sess = ksmbd_session_lookup_all(work->conn, ses_id);
1005 if (!sess)
1006 return -EINVAL;
1007
1008 ses_enc_key = enc ? sess->smb3encryptionkey :
1009 sess->smb3decryptionkey;
1010 memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
1011
1012 return 0;
1013}
1014
1015static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
1016 unsigned int buflen)
1017{
1018 void *addr;
1019
1020 if (is_vmalloc_addr(buf))
1021 addr = vmalloc_to_page(buf);
1022 else
1023 addr = virt_to_page(buf);
1024 sg_set_page(sg, addr, buflen, offset_in_page(buf));
1025}
1026
1027static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
1028 u8 *sign)
1029{
1030 struct scatterlist *sg;
1031 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1032 int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0;
1033
1034 if (!nvec)
1035 return NULL;
1036
1037 for (i = 0; i < nvec - 1; i++) {
1038 unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
1039
1040 if (is_vmalloc_addr(iov[i + 1].iov_base)) {
1041 nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
1042 PAGE_SIZE - 1) >> PAGE_SHIFT) -
1043 (kaddr >> PAGE_SHIFT);
1044 } else {
1045 nr_entries[i]++;
1046 }
1047 total_entries += nr_entries[i];
1048 }
1049
1050 /* Add two entries for transform header and signature */
1051 total_entries += 2;
1052
1053 sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
1054 if (!sg)
1055 return NULL;
1056
1057 sg_init_table(sg, total_entries);
1058 smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1059 for (i = 0; i < nvec - 1; i++) {
1060 void *data = iov[i + 1].iov_base;
1061 int len = iov[i + 1].iov_len;
1062
1063 if (is_vmalloc_addr(data)) {
1064 int j, offset = offset_in_page(data);
1065
1066 for (j = 0; j < nr_entries[i]; j++) {
1067 unsigned int bytes = PAGE_SIZE - offset;
1068
1069 if (!len)
1070 break;
1071
1072 if (bytes > len)
1073 bytes = len;
1074
1075 sg_set_page(&sg[sg_idx++],
1076 vmalloc_to_page(data), bytes,
1077 offset_in_page(data));
1078
1079 data += bytes;
1080 len -= bytes;
1081 offset = 0;
1082 }
1083 } else {
1084 sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1085 offset_in_page(data));
1086 }
1087 }
1088 smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1089 return sg;
1090}
1091
1092int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
1093 unsigned int nvec, int enc)
1094{
1095 struct ksmbd_conn *conn = work->conn;
1096 struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
1097 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1098 int rc;
1099 struct scatterlist *sg;
1100 u8 sign[SMB2_SIGNATURE_SIZE] = {};
1101 u8 key[SMB3_ENC_DEC_KEY_SIZE];
1102 struct aead_request *req;
1103 char *iv;
1104 unsigned int iv_len;
1105 struct crypto_aead *tfm;
1106 unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1107 struct ksmbd_crypto_ctx *ctx;
1108
1109 rc = ksmbd_get_encryption_key(work,
1110 le64_to_cpu(tr_hdr->SessionId),
1111 enc,
1112 key);
1113 if (rc) {
1114 pr_err("Could not get %scryption key\n", enc ? "en" : "de");
1115 return rc;
1116 }
1117
1118 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1119 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1120 ctx = ksmbd_crypto_ctx_find_gcm();
1121 else
1122 ctx = ksmbd_crypto_ctx_find_ccm();
1123 if (!ctx) {
1124 pr_err("crypto alloc failed\n");
1125 return -ENOMEM;
1126 }
1127
1128 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1129 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1130 tfm = CRYPTO_GCM(ctx);
1131 else
1132 tfm = CRYPTO_CCM(ctx);
1133
1134 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1135 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1136 rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1137 else
1138 rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
1139 if (rc) {
1140 pr_err("Failed to set aead key %d\n", rc);
1141 goto free_ctx;
1142 }
1143
1144 rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1145 if (rc) {
1146 pr_err("Failed to set authsize %d\n", rc);
1147 goto free_ctx;
1148 }
1149
1150 req = aead_request_alloc(tfm, GFP_KERNEL);
1151 if (!req) {
1152 rc = -ENOMEM;
1153 goto free_ctx;
1154 }
1155
1156 if (!enc) {
1157 memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1158 crypt_len += SMB2_SIGNATURE_SIZE;
1159 }
1160
1161 sg = ksmbd_init_sg(iov, nvec, sign);
1162 if (!sg) {
1163 pr_err("Failed to init sg\n");
1164 rc = -ENOMEM;
1165 goto free_req;
1166 }
1167
1168 iv_len = crypto_aead_ivsize(tfm);
1169 iv = kzalloc(iv_len, GFP_KERNEL);
1170 if (!iv) {
1171 rc = -ENOMEM;
1172 goto free_sg;
1173 }
1174
1175 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1176 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1177 memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
1178 } else {
1179 iv[0] = 3;
1180 memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
1181 }
1182
1183 aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1184 aead_request_set_ad(req, assoc_data_len);
1185 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1186
1187 if (enc)
1188 rc = crypto_aead_encrypt(req);
1189 else
1190 rc = crypto_aead_decrypt(req);
1191 if (rc)
1192 goto free_iv;
1193
1194 if (enc)
1195 memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1196
1197free_iv:
1198 kfree(iv);
1199free_sg:
1200 kfree(sg);
1201free_req:
1202 kfree(req);
1203free_ctx:
1204 ksmbd_release_crypto_ctx(ctx);
1205 return rc;
1206}