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