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