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