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