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