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