a89de24aa576ce46b7d16d51dc9872bc28a744cf
[linux-2.6-microblaze.git] / fs / cifsd / 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 "buffer_pool.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 static void
73 str_to_key(unsigned char *str, unsigned char *key)
74 {
75         int i;
76
77         key[0] = str[0] >> 1;
78         key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
79         key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
80         key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
81         key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
82         key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
83         key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
84         key[7] = str[6] & 0x7F;
85         for (i = 0; i < 8; i++)
86                 key[i] = (key[i] << 1);
87 }
88
89 static int
90 smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
91 {
92         unsigned char key2[8];
93         struct des_ctx ctx;
94
95         if (fips_enabled) {
96                 ksmbd_debug(AUTH,
97                         "FIPS compliance enabled: DES not permitted\n");
98                 return -ENOENT;
99         }
100
101         str_to_key(key, key2);
102         des_expand_key(&ctx, key2, DES_KEY_SIZE);
103         des_encrypt(&ctx, out, in);
104         memzero_explicit(&ctx, sizeof(ctx));
105         return 0;
106 }
107
108 static int ksmbd_enc_p24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
109 {
110         int rc;
111
112         rc = smbhash(p24, c8, p21);
113         if (rc)
114                 return rc;
115         rc = smbhash(p24 + 8, c8, p21 + 7);
116         if (rc)
117                 return rc;
118         return smbhash(p24 + 16, c8, p21 + 14);
119 }
120
121 /* produce a md4 message digest from data of length n bytes */
122 static int ksmbd_enc_md4(unsigned char *md4_hash, unsigned char *link_str,
123                 int link_len)
124 {
125         int rc;
126         struct ksmbd_crypto_ctx *ctx;
127
128         ctx = ksmbd_crypto_ctx_find_md4();
129         if (!ctx) {
130                 ksmbd_debug(AUTH, "Crypto md4 allocation error\n");
131                 return -EINVAL;
132         }
133
134         rc = crypto_shash_init(CRYPTO_MD4(ctx));
135         if (rc) {
136                 ksmbd_debug(AUTH, "Could not init md4 shash\n");
137                 goto out;
138         }
139
140         rc = crypto_shash_update(CRYPTO_MD4(ctx), link_str, link_len);
141         if (rc) {
142                 ksmbd_debug(AUTH, "Could not update with link_str\n");
143                 goto out;
144         }
145
146         rc = crypto_shash_final(CRYPTO_MD4(ctx), md4_hash);
147         if (rc)
148                 ksmbd_debug(AUTH, "Could not generate md4 hash\n");
149 out:
150         ksmbd_release_crypto_ctx(ctx);
151         return rc;
152 }
153
154 static int ksmbd_enc_update_sess_key(unsigned char *md5_hash, char *nonce,
155                 char *server_challenge, int len)
156 {
157         int rc;
158         struct ksmbd_crypto_ctx *ctx;
159
160         ctx = ksmbd_crypto_ctx_find_md5();
161         if (!ctx) {
162                 ksmbd_debug(AUTH, "Crypto md5 allocation error\n");
163                 return -EINVAL;
164         }
165
166         rc = crypto_shash_init(CRYPTO_MD5(ctx));
167         if (rc) {
168                 ksmbd_debug(AUTH, "Could not init md5 shash\n");
169                 goto out;
170         }
171
172         rc = crypto_shash_update(CRYPTO_MD5(ctx), server_challenge, len);
173         if (rc) {
174                 ksmbd_debug(AUTH, "Could not update with challenge\n");
175                 goto out;
176         }
177
178         rc = crypto_shash_update(CRYPTO_MD5(ctx), nonce, len);
179         if (rc) {
180                 ksmbd_debug(AUTH, "Could not update with nonce\n");
181                 goto out;
182         }
183
184         rc = crypto_shash_final(CRYPTO_MD5(ctx), md5_hash);
185         if (rc)
186                 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
187 out:
188         ksmbd_release_crypto_ctx(ctx);
189         return rc;
190 }
191
192 /**
193  * ksmbd_gen_sess_key() - function to generate session key
194  * @sess:       session of connection
195  * @hash:       source hash value to be used for find session key
196  * @hmac:       source hmac value to be used for finding session key
197  *
198  */
199 static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
200                 char *hmac)
201 {
202         struct ksmbd_crypto_ctx *ctx;
203         int rc = -EINVAL;
204
205         ctx = ksmbd_crypto_ctx_find_hmacmd5();
206         if (!ctx)
207                 goto out;
208
209         rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
210                                  hash,
211                                  CIFS_HMAC_MD5_HASH_SIZE);
212         if (rc) {
213                 ksmbd_debug(AUTH, "hmacmd5 set key fail error %d\n", rc);
214                 goto out;
215         }
216
217         rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
218         if (rc) {
219                 ksmbd_debug(AUTH, "could not init hmacmd5 error %d\n", rc);
220                 goto out;
221         }
222
223         rc = crypto_shash_update(CRYPTO_HMACMD5(ctx),
224                                  hmac,
225                                  SMB2_NTLMV2_SESSKEY_SIZE);
226         if (rc) {
227                 ksmbd_debug(AUTH, "Could not update with response error %d\n",
228                         rc);
229                 goto out;
230         }
231
232         rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
233         if (rc) {
234                 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
235                         rc);
236                 goto out;
237         }
238
239 out:
240         ksmbd_release_crypto_ctx(ctx);
241         return rc;
242 }
243
244 static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
245                 char *dname)
246 {
247         int ret = -EINVAL, len;
248         wchar_t *domain = NULL;
249         __le16 *uniname = NULL;
250         struct ksmbd_crypto_ctx *ctx;
251
252         ctx = ksmbd_crypto_ctx_find_hmacmd5();
253         if (!ctx) {
254                 ksmbd_debug(AUTH, "can't generate ntlmv2 hash\n");
255                 goto out;
256         }
257
258         ret = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
259                                   user_passkey(sess->user),
260                                   CIFS_ENCPWD_SIZE);
261         if (ret) {
262                 ksmbd_debug(AUTH, "Could not set NT Hash as a key\n");
263                 goto out;
264         }
265
266         ret = crypto_shash_init(CRYPTO_HMACMD5(ctx));
267         if (ret) {
268                 ksmbd_debug(AUTH, "could not init hmacmd5\n");
269                 goto out;
270         }
271
272         /* convert user_name to unicode */
273         len = strlen(user_name(sess->user));
274         uniname = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
275         if (!uniname) {
276                 ret = -ENOMEM;
277                 goto out;
278         }
279
280         if (len) {
281                 len = smb_strtoUTF16(uniname, user_name(sess->user), len,
282                         sess->conn->local_nls);
283                 UniStrupr(uniname);
284         }
285
286         ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
287                                   (char *)uniname,
288                                   UNICODE_LEN(len));
289         if (ret) {
290                 ksmbd_debug(AUTH, "Could not update with user\n");
291                 goto out;
292         }
293
294         /* Convert domain name or conn name to unicode and uppercase */
295         len = strlen(dname);
296         domain = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
297         if (!domain) {
298                 ret = -ENOMEM;
299                 goto out;
300         }
301
302         len = smb_strtoUTF16((__le16 *)domain, dname, len,
303                              sess->conn->local_nls);
304
305         ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
306                                   (char *)domain,
307                                   UNICODE_LEN(len));
308         if (ret) {
309                 ksmbd_debug(AUTH, "Could not update with domain\n");
310                 goto out;
311         }
312
313         ret = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_hash);
314         if (ret)
315                 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
316 out:
317         kfree(uniname);
318         kfree(domain);
319         ksmbd_release_crypto_ctx(ctx);
320         return ret;
321 }
322
323 /**
324  * ksmbd_auth_ntlm() - NTLM authentication handler
325  * @sess:       session of connection
326  * @pw_buf:     NTLM challenge response
327  * @passkey:    user password
328  *
329  * Return:      0 on success, error number on error
330  */
331 int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf)
332 {
333         int rc;
334         unsigned char p21[21];
335         char key[CIFS_AUTH_RESP_SIZE];
336
337         memset(p21, '\0', 21);
338         memcpy(p21, user_passkey(sess->user), CIFS_NTHASH_SIZE);
339         rc = ksmbd_enc_p24(p21, sess->ntlmssp.cryptkey, key);
340         if (rc) {
341                 ksmbd_err("password processing failed\n");
342                 return rc;
343         }
344
345         ksmbd_enc_md4(sess->sess_key,
346                         user_passkey(sess->user),
347                         CIFS_SMB1_SESSKEY_SIZE);
348         memcpy(sess->sess_key + CIFS_SMB1_SESSKEY_SIZE, key,
349                 CIFS_AUTH_RESP_SIZE);
350         sess->sequence_number = 1;
351
352         if (strncmp(pw_buf, key, CIFS_AUTH_RESP_SIZE) != 0) {
353                 ksmbd_debug(AUTH, "ntlmv1 authentication failed\n");
354                 return -EINVAL;
355         }
356
357         ksmbd_debug(AUTH, "ntlmv1 authentication pass\n");
358         return 0;
359 }
360
361 /**
362  * ksmbd_auth_ntlmv2() - NTLMv2 authentication handler
363  * @sess:       session of connection
364  * @ntlmv2:             NTLMv2 challenge response
365  * @blen:               NTLMv2 blob length
366  * @domain_name:        domain name
367  *
368  * Return:      0 on success, error number on error
369  */
370 int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
371                 int blen, char *domain_name)
372 {
373         char ntlmv2_hash[CIFS_ENCPWD_SIZE];
374         char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
375         struct ksmbd_crypto_ctx *ctx;
376         char *construct = NULL;
377         int rc = -EINVAL, len;
378
379         ctx = ksmbd_crypto_ctx_find_hmacmd5();
380         if (!ctx) {
381                 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5 rc %d\n", rc);
382                 goto out;
383         }
384
385         rc = calc_ntlmv2_hash(sess, ntlmv2_hash, domain_name);
386         if (rc) {
387                 ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
388                 goto out;
389         }
390
391         rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
392                                  ntlmv2_hash,
393                                  CIFS_HMAC_MD5_HASH_SIZE);
394         if (rc) {
395                 ksmbd_debug(AUTH, "Could not set NTLMV2 Hash as a key\n");
396                 goto out;
397         }
398
399         rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
400         if (rc) {
401                 ksmbd_debug(AUTH, "Could not init hmacmd5\n");
402                 goto out;
403         }
404
405         len = CIFS_CRYPTO_KEY_SIZE + blen;
406         construct = kzalloc(len, GFP_KERNEL);
407         if (!construct) {
408                 rc = -ENOMEM;
409                 goto out;
410         }
411
412         memcpy(construct, sess->ntlmssp.cryptkey, CIFS_CRYPTO_KEY_SIZE);
413         memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
414
415         rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
416         if (rc) {
417                 ksmbd_debug(AUTH, "Could not update with response\n");
418                 goto out;
419         }
420
421         rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_rsp);
422         if (rc) {
423                 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
424                 goto out;
425         }
426
427         rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
428         if (rc) {
429                 ksmbd_debug(AUTH, "Could not generate sess key\n");
430                 goto out;
431         }
432
433         if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
434                 rc = -EINVAL;
435 out:
436         ksmbd_release_crypto_ctx(ctx);
437         kfree(construct);
438         return rc;
439 }
440
441 /**
442  * __ksmbd_auth_ntlmv2() - NTLM2(extended security) authentication handler
443  * @sess:       session of connection
444  * @client_nonce:       client nonce from LM response.
445  * @ntlm_resp:          ntlm response data from client.
446  *
447  * Return:      0 on success, error number on error
448  */
449 static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce,
450                 char *ntlm_resp)
451 {
452         char sess_key[CIFS_SMB1_SESSKEY_SIZE] = {0};
453         int rc;
454         unsigned char p21[21];
455         char key[CIFS_AUTH_RESP_SIZE];
456
457         rc = ksmbd_enc_update_sess_key(sess_key,
458                                        client_nonce,
459                                        (char *)sess->ntlmssp.cryptkey, 8);
460         if (rc) {
461                 ksmbd_err("password processing failed\n");
462                 goto out;
463         }
464
465         memset(p21, '\0', 21);
466         memcpy(p21, user_passkey(sess->user), CIFS_NTHASH_SIZE);
467         rc = ksmbd_enc_p24(p21, sess_key, key);
468         if (rc) {
469                 ksmbd_err("password processing failed\n");
470                 goto out;
471         }
472
473         if (memcmp(ntlm_resp, key, CIFS_AUTH_RESP_SIZE) != 0)
474                 rc = -EINVAL;
475 out:
476         return rc;
477 }
478
479 /**
480  * ksmbd_decode_ntlmssp_auth_blob() - helper function to construct
481  * authenticate blob
482  * @authblob:   authenticate blob source pointer
483  * @usr:        user details
484  * @sess:       session of connection
485  *
486  * Return:      0 on success, error number on error
487  */
488 int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
489                 int blob_len, struct ksmbd_session *sess)
490 {
491         char *domain_name;
492         unsigned int lm_off, nt_off;
493         unsigned short nt_len;
494         int ret;
495
496         if (blob_len < sizeof(struct authenticate_message)) {
497                 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
498                         blob_len);
499                 return -EINVAL;
500         }
501
502         if (memcmp(authblob->Signature, "NTLMSSP", 8)) {
503                 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
504                                 authblob->Signature);
505                 return -EINVAL;
506         }
507
508         lm_off = le32_to_cpu(authblob->LmChallengeResponse.BufferOffset);
509         nt_off = le32_to_cpu(authblob->NtChallengeResponse.BufferOffset);
510         nt_len = le16_to_cpu(authblob->NtChallengeResponse.Length);
511
512         /* process NTLM authentication */
513         if (nt_len == CIFS_AUTH_RESP_SIZE) {
514                 if (le32_to_cpu(authblob->NegotiateFlags) &
515                     NTLMSSP_NEGOTIATE_EXTENDED_SEC)
516                         return __ksmbd_auth_ntlmv2(sess, (char *)authblob +
517                                 lm_off, (char *)authblob + nt_off);
518                 else
519                         return ksmbd_auth_ntlm(sess, (char *)authblob +
520                                 nt_off);
521         }
522
523         /* TODO : use domain name that imported from configuration file */
524         domain_name = smb_strndup_from_utf16((const char *)authblob +
525                         le32_to_cpu(authblob->DomainName.BufferOffset),
526                         le16_to_cpu(authblob->DomainName.Length), true,
527                         sess->conn->local_nls);
528         if (IS_ERR(domain_name))
529                 return PTR_ERR(domain_name);
530
531         /* process NTLMv2 authentication */
532         ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
533                         domain_name);
534         ret = ksmbd_auth_ntlmv2(sess,
535                         (struct ntlmv2_resp *)((char *)authblob + nt_off),
536                         nt_len - CIFS_ENCPWD_SIZE,
537                         domain_name);
538         kfree(domain_name);
539         return ret;
540 }
541
542 /**
543  * ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
544  * negotiate blob
545  * @negblob: negotiate blob source pointer
546  * @rsp:     response header pointer to be updated
547  * @sess:    session of connection
548  *
549  */
550 int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
551                 int blob_len, struct ksmbd_session *sess)
552 {
553         if (blob_len < sizeof(struct negotiate_message)) {
554                 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
555                         blob_len);
556                 return -EINVAL;
557         }
558
559         if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
560                 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
561                                 negblob->Signature);
562                 return -EINVAL;
563         }
564
565         sess->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
566         return 0;
567 }
568
569 /**
570  * ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
571  * challenge blob
572  * @chgblob: challenge blob source pointer to initialize
573  * @rsp:     response header pointer to be updated
574  * @sess:    session of connection
575  *
576  */
577 unsigned int
578 ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
579                 struct ksmbd_session *sess)
580 {
581         struct target_info *tinfo;
582         wchar_t *name;
583         __u8 *target_name;
584         unsigned int len, flags, blob_off, blob_len, type, target_info_len = 0;
585         int cflags = sess->ntlmssp.client_flags;
586
587         memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
588         chgblob->MessageType = NtLmChallenge;
589
590         flags = NTLMSSP_NEGOTIATE_UNICODE |
591                 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
592                 NTLMSSP_NEGOTIATE_TARGET_INFO;
593
594         if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
595                 flags |= NTLMSSP_NEGOTIATE_SIGN;
596                 flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
597                         NTLMSSP_NEGOTIATE_56);
598         }
599
600         if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
601                 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
602
603         if (cflags & NTLMSSP_REQUEST_TARGET)
604                 flags |= NTLMSSP_REQUEST_TARGET;
605
606         if (sess->conn->use_spnego &&
607             (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
608                 flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
609
610         chgblob->NegotiateFlags = cpu_to_le32(flags);
611         len = strlen(ksmbd_netbios_name());
612         name = kmalloc(2 + (len * 2), GFP_KERNEL);
613         if (!name)
614                 return -ENOMEM;
615
616         len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
617                         sess->conn->local_nls);
618         len = UNICODE_LEN(len);
619
620         blob_off = sizeof(struct challenge_message);
621         blob_len = blob_off + len;
622
623         chgblob->TargetName.Length = cpu_to_le16(len);
624         chgblob->TargetName.MaximumLength = cpu_to_le16(len);
625         chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
626
627         /* Initialize random conn challenge */
628         get_random_bytes(sess->ntlmssp.cryptkey, sizeof(__u64));
629         memcpy(chgblob->Challenge, sess->ntlmssp.cryptkey,
630                 CIFS_CRYPTO_KEY_SIZE);
631
632         /* Add Target Information to security buffer */
633         chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
634
635         target_name = (__u8 *)chgblob + blob_off;
636         memcpy(target_name, name, len);
637         tinfo = (struct target_info *)(target_name + len);
638
639         chgblob->TargetInfoArray.Length = 0;
640         /* Add target info list for NetBIOS/DNS settings */
641         for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
642                 type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
643                 tinfo->Type = cpu_to_le16(type);
644                 tinfo->Length = cpu_to_le16(len);
645                 memcpy(tinfo->Content, name, len);
646                 tinfo = (struct target_info *)((char *)tinfo + 4 + len);
647                 target_info_len += 4 + len;
648         }
649
650         /* Add terminator subblock */
651         tinfo->Type = 0;
652         tinfo->Length = 0;
653         target_info_len += 4;
654
655         chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
656         chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
657         blob_len += target_info_len;
658         kfree(name);
659         ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
660         return blob_len;
661 }
662
663 #ifdef CONFIG_SMB_SERVER_KERBEROS5
664 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
665                 int in_len, char *out_blob, int *out_len)
666 {
667         struct ksmbd_spnego_authen_response *resp;
668         struct ksmbd_user *user = NULL;
669         int retval;
670
671         resp = ksmbd_ipc_spnego_authen_request(in_blob, in_len);
672         if (!resp) {
673                 ksmbd_debug(AUTH, "SPNEGO_AUTHEN_REQUEST failure\n");
674                 return -EINVAL;
675         }
676
677         if (!(resp->login_response.status & KSMBD_USER_FLAG_OK)) {
678                 ksmbd_debug(AUTH, "krb5 authentication failure\n");
679                 retval = -EPERM;
680                 goto out;
681         }
682
683         if (*out_len <= resp->spnego_blob_len) {
684                 ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
685                                 *out_len, resp->spnego_blob_len);
686                 retval = -EINVAL;
687                 goto out;
688         }
689
690         if (resp->session_key_len > sizeof(sess->sess_key)) {
691                 ksmbd_debug(AUTH, "session key is too long\n");
692                 retval = -EINVAL;
693                 goto out;
694         }
695
696         user = ksmbd_alloc_user(&resp->login_response);
697         if (!user) {
698                 ksmbd_debug(AUTH, "login failure\n");
699                 retval = -ENOMEM;
700                 goto out;
701         }
702         sess->user = user;
703
704         memcpy(sess->sess_key, resp->payload, resp->session_key_len);
705         memcpy(out_blob, resp->payload + resp->session_key_len,
706                         resp->spnego_blob_len);
707         *out_len = resp->spnego_blob_len;
708         retval = 0;
709 out:
710         kvfree(resp);
711         return retval;
712 }
713 #else
714 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
715                 int in_len, char *out_blob, int *out_len)
716 {
717         return -EOPNOTSUPP;
718 }
719 #endif
720
721 /**
722  * ksmbd_sign_smb2_pdu() - function to generate packet signing
723  * @conn:       connection
724  * @key:        signing key
725  * @iov:        buffer iov array
726  * @n_vec:      number of iovecs
727  * @sig:        signature value generated for client request packet
728  *
729  */
730 int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
731                 int n_vec, char *sig)
732 {
733         struct ksmbd_crypto_ctx *ctx;
734         int rc = -EINVAL;
735         int i;
736
737         ctx = ksmbd_crypto_ctx_find_hmacsha256();
738         if (!ctx) {
739                 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5 rc %d\n", rc);
740                 goto out;
741         }
742
743         rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
744                                  key,
745                                  SMB2_NTLMV2_SESSKEY_SIZE);
746         if (rc)
747                 goto out;
748
749         rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
750         if (rc) {
751                 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
752                 goto out;
753         }
754
755         for (i = 0; i < n_vec; i++) {
756                 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
757                                          iov[i].iov_base,
758                                          iov[i].iov_len);
759                 if (rc) {
760                         ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
761                         goto out;
762                 }
763         }
764
765         rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
766         if (rc)
767                 ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
768 out:
769         ksmbd_release_crypto_ctx(ctx);
770         return rc;
771 }
772
773 /**
774  * ksmbd_sign_smb3_pdu() - function to generate packet signing
775  * @conn:       connection
776  * @key:        signing key
777  * @iov:        buffer iov array
778  * @n_vec:      number of iovecs
779  * @sig:        signature value generated for client request packet
780  *
781  */
782 int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
783                 int n_vec, char *sig)
784 {
785         struct ksmbd_crypto_ctx *ctx;
786         int rc = -EINVAL;
787         int i;
788
789         ctx = ksmbd_crypto_ctx_find_cmacaes();
790         if (!ctx) {
791                 ksmbd_debug(AUTH, "could not crypto alloc cmac rc %d\n", rc);
792                 goto out;
793         }
794
795         rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
796                                  key,
797                                  SMB2_CMACAES_SIZE);
798         if (rc)
799                 goto out;
800
801         rc = crypto_shash_init(CRYPTO_CMACAES(ctx));
802         if (rc) {
803                 ksmbd_debug(AUTH, "cmaces init error %d\n", rc);
804                 goto out;
805         }
806
807         for (i = 0; i < n_vec; i++) {
808                 rc = crypto_shash_update(CRYPTO_CMACAES(ctx),
809                                          iov[i].iov_base,
810                                          iov[i].iov_len);
811                 if (rc) {
812                         ksmbd_debug(AUTH, "cmaces update error %d\n", rc);
813                         goto out;
814                 }
815         }
816
817         rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig);
818         if (rc)
819                 ksmbd_debug(AUTH, "cmaces generation error %d\n", rc);
820 out:
821         ksmbd_release_crypto_ctx(ctx);
822         return rc;
823 }
824
825 struct derivation {
826         struct kvec label;
827         struct kvec context;
828         bool binding;
829 };
830
831 static int generate_key(struct ksmbd_session *sess, struct kvec label,
832                 struct kvec context, __u8 *key, unsigned int key_size)
833 {
834         unsigned char zero = 0x0;
835         __u8 i[4] = {0, 0, 0, 1};
836         __u8 L128[4] = {0, 0, 0, 128};
837         __u8 L256[4] = {0, 0, 1, 0};
838         int rc = -EINVAL;
839         unsigned char prfhash[SMB2_HMACSHA256_SIZE];
840         unsigned char *hashptr = prfhash;
841         struct ksmbd_crypto_ctx *ctx;
842
843         memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
844         memset(key, 0x0, key_size);
845
846         ctx = ksmbd_crypto_ctx_find_hmacsha256();
847         if (!ctx) {
848                 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5 rc %d\n", rc);
849                 goto smb3signkey_ret;
850         }
851
852         rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
853                                  sess->sess_key,
854                                  SMB2_NTLMV2_SESSKEY_SIZE);
855         if (rc)
856                 goto smb3signkey_ret;
857
858         rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
859         if (rc) {
860                 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
861                 goto smb3signkey_ret;
862         }
863
864         rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
865         if (rc) {
866                 ksmbd_debug(AUTH, "could not update with n\n");
867                 goto smb3signkey_ret;
868         }
869
870         rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
871                                  label.iov_base,
872                                  label.iov_len);
873         if (rc) {
874                 ksmbd_debug(AUTH, "could not update with label\n");
875                 goto smb3signkey_ret;
876         }
877
878         rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
879         if (rc) {
880                 ksmbd_debug(AUTH, "could not update with zero\n");
881                 goto smb3signkey_ret;
882         }
883
884         rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
885                                  context.iov_base,
886                                  context.iov_len);
887         if (rc) {
888                 ksmbd_debug(AUTH, "could not update with context\n");
889                 goto smb3signkey_ret;
890         }
891
892         if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
893             sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
894                 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
895         else
896                 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
897         if (rc) {
898                 ksmbd_debug(AUTH, "could not update with L\n");
899                 goto smb3signkey_ret;
900         }
901
902         rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
903         if (rc) {
904                 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
905                         rc);
906                 goto smb3signkey_ret;
907         }
908
909         memcpy(key, hashptr, key_size);
910
911 smb3signkey_ret:
912         ksmbd_release_crypto_ctx(ctx);
913         return rc;
914 }
915
916 static int generate_smb3signingkey(struct ksmbd_session *sess,
917                 const struct derivation *signing)
918 {
919         int rc;
920         struct channel *chann;
921         char *key;
922
923         chann = lookup_chann_list(sess);
924         if (!chann)
925                 return 0;
926
927         if (sess->conn->dialect >= SMB30_PROT_ID && signing->binding)
928                 key = chann->smb3signingkey;
929         else
930                 key = sess->smb3signingkey;
931
932         rc = generate_key(sess, signing->label, signing->context, key,
933                 SMB3_SIGN_KEY_SIZE);
934         if (rc)
935                 return rc;
936
937         if (!(sess->conn->dialect >= SMB30_PROT_ID && signing->binding))
938                 memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
939
940         ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
941         ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
942         ksmbd_debug(AUTH, "Session Key   %*ph\n",
943                         SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
944         ksmbd_debug(AUTH, "Signing Key   %*ph\n",
945                         SMB3_SIGN_KEY_SIZE, key);
946         return 0;
947 }
948
949 int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess)
950 {
951         struct derivation d;
952
953         d.label.iov_base = "SMB2AESCMAC";
954         d.label.iov_len = 12;
955         d.context.iov_base = "SmbSign";
956         d.context.iov_len = 8;
957         d.binding = false;
958
959         return generate_smb3signingkey(sess, &d);
960 }
961
962 int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess)
963 {
964         struct derivation d;
965
966         d.label.iov_base = "SMBSigningKey";
967         d.label.iov_len = 14;
968         d.context.iov_base = sess->Preauth_HashValue;
969         d.context.iov_len = 64;
970         d.binding = false;
971
972         return generate_smb3signingkey(sess, &d);
973 }
974
975 struct derivation_twin {
976         struct derivation encryption;
977         struct derivation decryption;
978 };
979
980 static int generate_smb3encryptionkey(struct ksmbd_session *sess,
981                 const struct derivation_twin *ptwin)
982 {
983         int rc;
984
985         rc = generate_key(sess, ptwin->encryption.label,
986                         ptwin->encryption.context, sess->smb3encryptionkey,
987                         SMB3_ENC_DEC_KEY_SIZE);
988         if (rc)
989                 return rc;
990
991         rc = generate_key(sess, ptwin->decryption.label,
992                         ptwin->decryption.context,
993                         sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
994         if (rc)
995                 return rc;
996
997         ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
998         ksmbd_debug(AUTH, "Cipher type   %d\n", sess->conn->cipher_type);
999         ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
1000         ksmbd_debug(AUTH, "Session Key   %*ph\n",
1001                         SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
1002         if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1003             sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1004                 ksmbd_debug(AUTH, "ServerIn Key  %*ph\n",
1005                         SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
1006                 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
1007                         SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
1008         } else {
1009                 ksmbd_debug(AUTH, "ServerIn Key  %*ph\n",
1010                         SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
1011                 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
1012                         SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
1013         }
1014         return 0;
1015 }
1016
1017 int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess)
1018 {
1019         struct derivation_twin twin;
1020         struct derivation *d;
1021
1022         d = &twin.encryption;
1023         d->label.iov_base = "SMB2AESCCM";
1024         d->label.iov_len = 11;
1025         d->context.iov_base = "ServerOut";
1026         d->context.iov_len = 10;
1027
1028         d = &twin.decryption;
1029         d->label.iov_base = "SMB2AESCCM";
1030         d->label.iov_len = 11;
1031         d->context.iov_base = "ServerIn ";
1032         d->context.iov_len = 10;
1033
1034         return generate_smb3encryptionkey(sess, &twin);
1035 }
1036
1037 int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
1038 {
1039         struct derivation_twin twin;
1040         struct derivation *d;
1041
1042         d = &twin.encryption;
1043         d->label.iov_base = "SMBS2CCipherKey";
1044         d->label.iov_len = 16;
1045         d->context.iov_base = sess->Preauth_HashValue;
1046         d->context.iov_len = 64;
1047
1048         d = &twin.decryption;
1049         d->label.iov_base = "SMBC2SCipherKey";
1050         d->label.iov_len = 16;
1051         d->context.iov_base = sess->Preauth_HashValue;
1052         d->context.iov_len = 64;
1053
1054         return generate_smb3encryptionkey(sess, &twin);
1055 }
1056
1057 int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
1058                 __u8 *pi_hash)
1059 {
1060         int rc = -1;
1061         struct smb2_hdr *rcv_hdr = (struct smb2_hdr *)buf;
1062         char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
1063         int msg_size = be32_to_cpu(rcv_hdr->smb2_buf_length);
1064         struct ksmbd_crypto_ctx *ctx = NULL;
1065
1066         if (conn->preauth_info->Preauth_HashId ==
1067             SMB2_PREAUTH_INTEGRITY_SHA512) {
1068                 ctx = ksmbd_crypto_ctx_find_sha512();
1069                 if (!ctx) {
1070                         ksmbd_debug(AUTH, "could not alloc sha512 rc %d\n", rc);
1071                         goto out;
1072                 }
1073         } else {
1074                 goto out;
1075         }
1076
1077         rc = crypto_shash_init(CRYPTO_SHA512(ctx));
1078         if (rc) {
1079                 ksmbd_debug(AUTH, "could not init shashn");
1080                 goto out;
1081         }
1082
1083         rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
1084         if (rc) {
1085                 ksmbd_debug(AUTH, "could not update with n\n");
1086                 goto out;
1087         }
1088
1089         rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
1090         if (rc) {
1091                 ksmbd_debug(AUTH, "could not update with n\n");
1092                 goto out;
1093         }
1094
1095         rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
1096         if (rc) {
1097                 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
1098                 goto out;
1099         }
1100 out:
1101         ksmbd_release_crypto_ctx(ctx);
1102         return rc;
1103 }
1104
1105 int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
1106                 __u8 *pi_hash)
1107 {
1108         int rc = -1;
1109         struct ksmbd_crypto_ctx *ctx = NULL;
1110
1111         ctx = ksmbd_crypto_ctx_find_sha256();
1112         if (!ctx) {
1113                 ksmbd_debug(AUTH, "could not alloc sha256 rc %d\n", rc);
1114                 goto out;
1115         }
1116
1117         rc = crypto_shash_init(CRYPTO_SHA256(ctx));
1118         if (rc) {
1119                 ksmbd_debug(AUTH, "could not init shashn");
1120                 goto out;
1121         }
1122
1123         rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
1124         if (rc) {
1125                 ksmbd_debug(AUTH, "could not update with n\n");
1126                 goto out;
1127         }
1128
1129         rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
1130         if (rc) {
1131                 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
1132                 goto out;
1133         }
1134 out:
1135         ksmbd_release_crypto_ctx(ctx);
1136         return rc;
1137 }
1138
1139 static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
1140                 int enc, u8 *key)
1141 {
1142         struct ksmbd_session *sess;
1143         u8 *ses_enc_key;
1144
1145         sess = ksmbd_session_lookup(conn, ses_id);
1146         if (!sess)
1147                 return 1;
1148
1149         ses_enc_key = enc ? sess->smb3encryptionkey :
1150                 sess->smb3decryptionkey;
1151         memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
1152
1153         return 0;
1154 }
1155
1156 static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
1157                 unsigned int buflen)
1158 {
1159         void *addr;
1160
1161         if (is_vmalloc_addr(buf))
1162                 addr = vmalloc_to_page(buf);
1163         else
1164                 addr = virt_to_page(buf);
1165         sg_set_page(sg, addr, buflen, offset_in_page(buf));
1166 }
1167
1168 static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
1169                 u8 *sign)
1170 {
1171         struct scatterlist *sg;
1172         unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
1173         int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0;
1174
1175         for (i = 0; i < nvec - 1; i++) {
1176                 unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
1177
1178                 if (is_vmalloc_addr(iov[i + 1].iov_base)) {
1179                         nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
1180                                         PAGE_SIZE - 1) >> PAGE_SHIFT) -
1181                                 (kaddr >> PAGE_SHIFT);
1182                 } else {
1183                         nr_entries[i]++;
1184                 }
1185                 total_entries += nr_entries[i];
1186         }
1187
1188         /* Add two entries for transform header and signature */
1189         total_entries += 2;
1190
1191         sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
1192         if (!sg)
1193                 return NULL;
1194
1195         sg_init_table(sg, total_entries);
1196         smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1197         for (i = 0; i < nvec - 1; i++) {
1198                 void *data = iov[i + 1].iov_base;
1199                 int len = iov[i + 1].iov_len;
1200
1201                 if (is_vmalloc_addr(data)) {
1202                         int j, offset = offset_in_page(data);
1203
1204                         for (j = 0; j < nr_entries[i]; j++) {
1205                                 unsigned int bytes = PAGE_SIZE - offset;
1206
1207                                 if (len <= 0)
1208                                         break;
1209
1210                                 if (bytes > len)
1211                                         bytes = len;
1212
1213                                 sg_set_page(&sg[sg_idx++],
1214                                             vmalloc_to_page(data), bytes,
1215                                             offset_in_page(data));
1216
1217                                 data += bytes;
1218                                 len -= bytes;
1219                                 offset = 0;
1220                         }
1221                 } else {
1222                         sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1223                                     offset_in_page(data));
1224                 }
1225         }
1226         smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1227         return sg;
1228 }
1229
1230 int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
1231                 unsigned int nvec, int enc)
1232 {
1233         struct smb2_transform_hdr *tr_hdr =
1234                 (struct smb2_transform_hdr *)iov[0].iov_base;
1235         unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
1236         int rc = 0;
1237         struct scatterlist *sg;
1238         u8 sign[SMB2_SIGNATURE_SIZE] = {};
1239         u8 key[SMB3_ENC_DEC_KEY_SIZE];
1240         struct aead_request *req;
1241         char *iv;
1242         unsigned int iv_len;
1243         struct crypto_aead *tfm;
1244         unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1245         struct ksmbd_crypto_ctx *ctx;
1246
1247         rc = ksmbd_get_encryption_key(conn,
1248                                       le64_to_cpu(tr_hdr->SessionId),
1249                                       enc,
1250                                       key);
1251         if (rc) {
1252                 ksmbd_err("Could not get %scryption key\n", enc ? "en" : "de");
1253                 return 0;
1254         }
1255
1256         if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1257             conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1258                 ctx = ksmbd_crypto_ctx_find_gcm();
1259         else
1260                 ctx = ksmbd_crypto_ctx_find_ccm();
1261         if (!ctx) {
1262                 ksmbd_err("crypto alloc failed\n");
1263                 return -EINVAL;
1264         }
1265
1266         if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1267             conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1268                 tfm = CRYPTO_GCM(ctx);
1269         else
1270                 tfm = CRYPTO_CCM(ctx);
1271
1272         if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1273             conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1274                 rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1275         else
1276                 rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
1277         if (rc) {
1278                 ksmbd_err("Failed to set aead key %d\n", rc);
1279                 goto free_ctx;
1280         }
1281
1282         rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1283         if (rc) {
1284                 ksmbd_err("Failed to set authsize %d\n", rc);
1285                 goto free_ctx;
1286         }
1287
1288         req = aead_request_alloc(tfm, GFP_KERNEL);
1289         if (!req) {
1290                 ksmbd_err("Failed to alloc aead request\n");
1291                 rc = -ENOMEM;
1292                 goto free_ctx;
1293         }
1294
1295         if (!enc) {
1296                 memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1297                 crypt_len += SMB2_SIGNATURE_SIZE;
1298         }
1299
1300         sg = ksmbd_init_sg(iov, nvec, sign);
1301         if (!sg) {
1302                 ksmbd_err("Failed to init sg\n");
1303                 rc = -ENOMEM;
1304                 goto free_req;
1305         }
1306
1307         iv_len = crypto_aead_ivsize(tfm);
1308         iv = kzalloc(iv_len, GFP_KERNEL);
1309         if (!iv) {
1310                 ksmbd_err("Failed to alloc IV\n");
1311                 rc = -ENOMEM;
1312                 goto free_sg;
1313         }
1314
1315         if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1316             conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1317                 memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
1318         } else {
1319                 iv[0] = 3;
1320                 memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
1321         }
1322
1323         aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1324         aead_request_set_ad(req, assoc_data_len);
1325         aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1326
1327         if (enc)
1328                 rc = crypto_aead_encrypt(req);
1329         else
1330                 rc = crypto_aead_decrypt(req);
1331         if (!rc && enc)
1332                 memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1333
1334         kfree(iv);
1335 free_sg:
1336         kfree(sg);
1337 free_req:
1338         kfree(req);
1339 free_ctx:
1340         ksmbd_release_crypto_ctx(ctx);
1341         return rc;
1342 }