Merge tag 'drm-misc-next-2021-10-14' of git://anongit.freedesktop.org/drm/drm-misc...
[linux-2.6-microblaze.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
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
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  */
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
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  */
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  */
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  */
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
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
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
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  */
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  */
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }