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