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), GFP_KERNEL);
155 if (!uniname) {
156 ret = -ENOMEM;
157 goto out;
158 }
159
160 conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
161 conn->local_nls);
162 if (conv_len < 0 || conv_len > len) {
163 ret = -EINVAL;
164 goto out;
165 }
166 UniStrupr(uniname);
167
168 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
169 (char *)uniname,
170 UNICODE_LEN(conv_len));
171 if (ret) {
172 ksmbd_debug(AUTH, "Could not update with user\n");
173 goto out;
174 }
175
176 /* Convert domain name or conn name to unicode and uppercase */
177 len = strlen(dname);
178 domain = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
179 if (!domain) {
180 ret = -ENOMEM;
181 goto out;
182 }
183
184 conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
185 conn->local_nls);
186 if (conv_len < 0 || conv_len > len) {
187 ret = -EINVAL;
188 goto out;
189 }
190
191 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
192 (char *)domain,
193 UNICODE_LEN(conv_len));
194 if (ret) {
195 ksmbd_debug(AUTH, "Could not update with domain\n");
196 goto out;
197 }
198
199 ret = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_hash);
200 if (ret)
201 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
202 out:
203 kfree(uniname);
204 kfree(domain);
205 ksmbd_release_crypto_ctx(ctx);
206 return ret;
207 }
208
209 /**
210 * ksmbd_auth_ntlmv2() - NTLMv2 authentication handler
211 * @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, GFP_KERNEL);
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), GFP_KERNEL);
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), GFP_KERNEL);
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_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 user = ksmbd_alloc_user(&resp->login_response);
544 if (!user) {
545 ksmbd_debug(AUTH, "login failure\n");
546 retval = -ENOMEM;
547 goto out;
548 }
549
550 if (!sess->user) {
551 /* First successful authentication */
552 sess->user = user;
553 } else {
554 if (!ksmbd_compare_user(sess->user, user)) {
555 ksmbd_debug(AUTH, "different user tried to reuse session\n");
556 retval = -EPERM;
557 ksmbd_free_user(user);
558 goto out;
559 }
560 ksmbd_free_user(user);
561 }
562
563 memcpy(sess->sess_key, resp->payload, resp->session_key_len);
564 memcpy(out_blob, resp->payload + resp->session_key_len,
565 resp->spnego_blob_len);
566 *out_len = resp->spnego_blob_len;
567 retval = 0;
568 out:
569 kvfree(resp);
570 return retval;
571 }
572 #else
ksmbd_krb5_authenticate(struct ksmbd_session * sess,char * in_blob,int in_len,char * out_blob,int * out_len)573 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
574 int in_len, char *out_blob, int *out_len)
575 {
576 return -EOPNOTSUPP;
577 }
578 #endif
579
580 /**
581 * ksmbd_sign_smb2_pdu() - function to generate packet signing
582 * @conn: connection
583 * @key: signing key
584 * @iov: buffer iov array
585 * @n_vec: number of iovecs
586 * @sig: signature value generated for client request packet
587 *
588 */
ksmbd_sign_smb2_pdu(struct ksmbd_conn * conn,char * key,struct kvec * iov,int n_vec,char * sig)589 int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
590 int n_vec, char *sig)
591 {
592 struct ksmbd_crypto_ctx *ctx;
593 int rc, i;
594
595 ctx = ksmbd_crypto_ctx_find_hmacsha256();
596 if (!ctx) {
597 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
598 return -ENOMEM;
599 }
600
601 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
602 key,
603 SMB2_NTLMV2_SESSKEY_SIZE);
604 if (rc)
605 goto out;
606
607 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
608 if (rc) {
609 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
610 goto out;
611 }
612
613 for (i = 0; i < n_vec; i++) {
614 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
615 iov[i].iov_base,
616 iov[i].iov_len);
617 if (rc) {
618 ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
619 goto out;
620 }
621 }
622
623 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
624 if (rc)
625 ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
626 out:
627 ksmbd_release_crypto_ctx(ctx);
628 return rc;
629 }
630
631 /**
632 * ksmbd_sign_smb3_pdu() - function to generate packet signing
633 * @conn: connection
634 * @key: signing key
635 * @iov: buffer iov array
636 * @n_vec: number of iovecs
637 * @sig: signature value generated for client request packet
638 *
639 */
ksmbd_sign_smb3_pdu(struct ksmbd_conn * conn,char * key,struct kvec * iov,int n_vec,char * sig)640 int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
641 int n_vec, char *sig)
642 {
643 struct ksmbd_crypto_ctx *ctx;
644 int rc, i;
645
646 ctx = ksmbd_crypto_ctx_find_cmacaes();
647 if (!ctx) {
648 ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
649 return -ENOMEM;
650 }
651
652 rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
653 key,
654 SMB2_CMACAES_SIZE);
655 if (rc)
656 goto out;
657
658 rc = crypto_shash_init(CRYPTO_CMACAES(ctx));
659 if (rc) {
660 ksmbd_debug(AUTH, "cmaces init error %d\n", rc);
661 goto out;
662 }
663
664 for (i = 0; i < n_vec; i++) {
665 rc = crypto_shash_update(CRYPTO_CMACAES(ctx),
666 iov[i].iov_base,
667 iov[i].iov_len);
668 if (rc) {
669 ksmbd_debug(AUTH, "cmaces update error %d\n", rc);
670 goto out;
671 }
672 }
673
674 rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig);
675 if (rc)
676 ksmbd_debug(AUTH, "cmaces generation error %d\n", rc);
677 out:
678 ksmbd_release_crypto_ctx(ctx);
679 return rc;
680 }
681
682 struct derivation {
683 struct kvec label;
684 struct kvec context;
685 bool binding;
686 };
687
generate_key(struct ksmbd_conn * conn,struct ksmbd_session * sess,struct kvec label,struct kvec context,__u8 * key,unsigned int key_size)688 static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
689 struct kvec label, struct kvec context, __u8 *key,
690 unsigned int key_size)
691 {
692 unsigned char zero = 0x0;
693 __u8 i[4] = {0, 0, 0, 1};
694 __u8 L128[4] = {0, 0, 0, 128};
695 __u8 L256[4] = {0, 0, 1, 0};
696 int rc;
697 unsigned char prfhash[SMB2_HMACSHA256_SIZE];
698 unsigned char *hashptr = prfhash;
699 struct ksmbd_crypto_ctx *ctx;
700
701 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
702 memset(key, 0x0, key_size);
703
704 ctx = ksmbd_crypto_ctx_find_hmacsha256();
705 if (!ctx) {
706 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
707 return -ENOMEM;
708 }
709
710 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
711 sess->sess_key,
712 SMB2_NTLMV2_SESSKEY_SIZE);
713 if (rc)
714 goto smb3signkey_ret;
715
716 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
717 if (rc) {
718 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
719 goto smb3signkey_ret;
720 }
721
722 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
723 if (rc) {
724 ksmbd_debug(AUTH, "could not update with n\n");
725 goto smb3signkey_ret;
726 }
727
728 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
729 label.iov_base,
730 label.iov_len);
731 if (rc) {
732 ksmbd_debug(AUTH, "could not update with label\n");
733 goto smb3signkey_ret;
734 }
735
736 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
737 if (rc) {
738 ksmbd_debug(AUTH, "could not update with zero\n");
739 goto smb3signkey_ret;
740 }
741
742 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
743 context.iov_base,
744 context.iov_len);
745 if (rc) {
746 ksmbd_debug(AUTH, "could not update with context\n");
747 goto smb3signkey_ret;
748 }
749
750 if (key_size == SMB3_ENC_DEC_KEY_SIZE &&
751 (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
752 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
753 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
754 else
755 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
756 if (rc) {
757 ksmbd_debug(AUTH, "could not update with L\n");
758 goto smb3signkey_ret;
759 }
760
761 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
762 if (rc) {
763 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
764 rc);
765 goto smb3signkey_ret;
766 }
767
768 memcpy(key, hashptr, key_size);
769
770 smb3signkey_ret:
771 ksmbd_release_crypto_ctx(ctx);
772 return rc;
773 }
774
generate_smb3signingkey(struct ksmbd_session * sess,struct ksmbd_conn * conn,const struct derivation * signing)775 static int generate_smb3signingkey(struct ksmbd_session *sess,
776 struct ksmbd_conn *conn,
777 const struct derivation *signing)
778 {
779 int rc;
780 struct channel *chann;
781 char *key;
782
783 chann = lookup_chann_list(sess, conn);
784 if (!chann)
785 return 0;
786
787 if (conn->dialect >= SMB30_PROT_ID && signing->binding)
788 key = chann->smb3signingkey;
789 else
790 key = sess->smb3signingkey;
791
792 rc = generate_key(conn, sess, signing->label, signing->context, key,
793 SMB3_SIGN_KEY_SIZE);
794 if (rc)
795 return rc;
796
797 if (!(conn->dialect >= SMB30_PROT_ID && signing->binding))
798 memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
799
800 ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
801 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
802 ksmbd_debug(AUTH, "Session Key %*ph\n",
803 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
804 ksmbd_debug(AUTH, "Signing Key %*ph\n",
805 SMB3_SIGN_KEY_SIZE, key);
806 return 0;
807 }
808
ksmbd_gen_smb30_signingkey(struct ksmbd_session * sess,struct ksmbd_conn * conn)809 int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
810 struct ksmbd_conn *conn)
811 {
812 struct derivation d;
813
814 d.label.iov_base = "SMB2AESCMAC";
815 d.label.iov_len = 12;
816 d.context.iov_base = "SmbSign";
817 d.context.iov_len = 8;
818 d.binding = conn->binding;
819
820 return generate_smb3signingkey(sess, conn, &d);
821 }
822
ksmbd_gen_smb311_signingkey(struct ksmbd_session * sess,struct ksmbd_conn * conn)823 int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
824 struct ksmbd_conn *conn)
825 {
826 struct derivation d;
827
828 d.label.iov_base = "SMBSigningKey";
829 d.label.iov_len = 14;
830 if (conn->binding) {
831 struct preauth_session *preauth_sess;
832
833 preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
834 if (!preauth_sess)
835 return -ENOENT;
836 d.context.iov_base = preauth_sess->Preauth_HashValue;
837 } else {
838 d.context.iov_base = sess->Preauth_HashValue;
839 }
840 d.context.iov_len = 64;
841 d.binding = conn->binding;
842
843 return generate_smb3signingkey(sess, conn, &d);
844 }
845
846 struct derivation_twin {
847 struct derivation encryption;
848 struct derivation decryption;
849 };
850
generate_smb3encryptionkey(struct ksmbd_conn * conn,struct ksmbd_session * sess,const struct derivation_twin * ptwin)851 static int generate_smb3encryptionkey(struct ksmbd_conn *conn,
852 struct ksmbd_session *sess,
853 const struct derivation_twin *ptwin)
854 {
855 int rc;
856
857 rc = generate_key(conn, sess, ptwin->encryption.label,
858 ptwin->encryption.context, sess->smb3encryptionkey,
859 SMB3_ENC_DEC_KEY_SIZE);
860 if (rc)
861 return rc;
862
863 rc = generate_key(conn, sess, ptwin->decryption.label,
864 ptwin->decryption.context,
865 sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
866 if (rc)
867 return rc;
868
869 ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
870 ksmbd_debug(AUTH, "Cipher type %d\n", conn->cipher_type);
871 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
872 ksmbd_debug(AUTH, "Session Key %*ph\n",
873 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
874 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
875 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
876 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
877 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
878 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
879 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
880 } else {
881 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
882 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
883 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
884 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
885 }
886 return 0;
887 }
888
ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn * conn,struct ksmbd_session * sess)889 int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
890 struct ksmbd_session *sess)
891 {
892 struct derivation_twin twin;
893 struct derivation *d;
894
895 d = &twin.encryption;
896 d->label.iov_base = "SMB2AESCCM";
897 d->label.iov_len = 11;
898 d->context.iov_base = "ServerOut";
899 d->context.iov_len = 10;
900
901 d = &twin.decryption;
902 d->label.iov_base = "SMB2AESCCM";
903 d->label.iov_len = 11;
904 d->context.iov_base = "ServerIn ";
905 d->context.iov_len = 10;
906
907 return generate_smb3encryptionkey(conn, sess, &twin);
908 }
909
ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn * conn,struct ksmbd_session * sess)910 int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
911 struct ksmbd_session *sess)
912 {
913 struct derivation_twin twin;
914 struct derivation *d;
915
916 d = &twin.encryption;
917 d->label.iov_base = "SMBS2CCipherKey";
918 d->label.iov_len = 16;
919 d->context.iov_base = sess->Preauth_HashValue;
920 d->context.iov_len = 64;
921
922 d = &twin.decryption;
923 d->label.iov_base = "SMBC2SCipherKey";
924 d->label.iov_len = 16;
925 d->context.iov_base = sess->Preauth_HashValue;
926 d->context.iov_len = 64;
927
928 return generate_smb3encryptionkey(conn, sess, &twin);
929 }
930
ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn * conn,char * buf,__u8 * pi_hash)931 int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
932 __u8 *pi_hash)
933 {
934 int rc;
935 struct smb2_hdr *rcv_hdr = smb2_get_msg(buf);
936 char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
937 int msg_size = get_rfc1002_len(buf);
938 struct ksmbd_crypto_ctx *ctx = NULL;
939
940 if (conn->preauth_info->Preauth_HashId !=
941 SMB2_PREAUTH_INTEGRITY_SHA512)
942 return -EINVAL;
943
944 ctx = ksmbd_crypto_ctx_find_sha512();
945 if (!ctx) {
946 ksmbd_debug(AUTH, "could not alloc sha512\n");
947 return -ENOMEM;
948 }
949
950 rc = crypto_shash_init(CRYPTO_SHA512(ctx));
951 if (rc) {
952 ksmbd_debug(AUTH, "could not init shashn");
953 goto out;
954 }
955
956 rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
957 if (rc) {
958 ksmbd_debug(AUTH, "could not update with n\n");
959 goto out;
960 }
961
962 rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
963 if (rc) {
964 ksmbd_debug(AUTH, "could not update with n\n");
965 goto out;
966 }
967
968 rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
969 if (rc) {
970 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
971 goto out;
972 }
973 out:
974 ksmbd_release_crypto_ctx(ctx);
975 return rc;
976 }
977
ksmbd_gen_sd_hash(struct ksmbd_conn * conn,char * sd_buf,int len,__u8 * pi_hash)978 int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
979 __u8 *pi_hash)
980 {
981 int rc;
982 struct ksmbd_crypto_ctx *ctx = NULL;
983
984 ctx = ksmbd_crypto_ctx_find_sha256();
985 if (!ctx) {
986 ksmbd_debug(AUTH, "could not alloc sha256\n");
987 return -ENOMEM;
988 }
989
990 rc = crypto_shash_init(CRYPTO_SHA256(ctx));
991 if (rc) {
992 ksmbd_debug(AUTH, "could not init shashn");
993 goto out;
994 }
995
996 rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
997 if (rc) {
998 ksmbd_debug(AUTH, "could not update with n\n");
999 goto out;
1000 }
1001
1002 rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
1003 if (rc) {
1004 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
1005 goto out;
1006 }
1007 out:
1008 ksmbd_release_crypto_ctx(ctx);
1009 return rc;
1010 }
1011
ksmbd_get_encryption_key(struct ksmbd_work * work,__u64 ses_id,int enc,u8 * key)1012 static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id,
1013 int enc, u8 *key)
1014 {
1015 struct ksmbd_session *sess;
1016 u8 *ses_enc_key;
1017
1018 if (enc)
1019 sess = work->sess;
1020 else
1021 sess = ksmbd_session_lookup_all(work->conn, ses_id);
1022 if (!sess)
1023 return -EINVAL;
1024
1025 ses_enc_key = enc ? sess->smb3encryptionkey :
1026 sess->smb3decryptionkey;
1027 memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
1028 if (!enc)
1029 ksmbd_user_session_put(sess);
1030
1031 return 0;
1032 }
1033
smb2_sg_set_buf(struct scatterlist * sg,const void * buf,unsigned int buflen)1034 static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
1035 unsigned int buflen)
1036 {
1037 void *addr;
1038
1039 if (is_vmalloc_addr(buf))
1040 addr = vmalloc_to_page(buf);
1041 else
1042 addr = virt_to_page(buf);
1043 sg_set_page(sg, addr, buflen, offset_in_page(buf));
1044 }
1045
ksmbd_init_sg(struct kvec * iov,unsigned int nvec,u8 * sign)1046 static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
1047 u8 *sign)
1048 {
1049 struct scatterlist *sg;
1050 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1051 int i, *nr_entries, total_entries = 0, sg_idx = 0;
1052
1053 if (!nvec)
1054 return NULL;
1055
1056 nr_entries = kcalloc(nvec, sizeof(int), GFP_KERNEL);
1057 if (!nr_entries)
1058 return NULL;
1059
1060 for (i = 0; i < nvec - 1; i++) {
1061 unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
1062
1063 if (is_vmalloc_addr(iov[i + 1].iov_base)) {
1064 nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
1065 PAGE_SIZE - 1) >> PAGE_SHIFT) -
1066 (kaddr >> PAGE_SHIFT);
1067 } else {
1068 nr_entries[i]++;
1069 }
1070 total_entries += nr_entries[i];
1071 }
1072
1073 /* Add two entries for transform header and signature */
1074 total_entries += 2;
1075
1076 sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
1077 if (!sg) {
1078 kfree(nr_entries);
1079 return NULL;
1080 }
1081
1082 sg_init_table(sg, total_entries);
1083 smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1084 for (i = 0; i < nvec - 1; i++) {
1085 void *data = iov[i + 1].iov_base;
1086 int len = iov[i + 1].iov_len;
1087
1088 if (is_vmalloc_addr(data)) {
1089 int j, offset = offset_in_page(data);
1090
1091 for (j = 0; j < nr_entries[i]; j++) {
1092 unsigned int bytes = PAGE_SIZE - offset;
1093
1094 if (!len)
1095 break;
1096
1097 if (bytes > len)
1098 bytes = len;
1099
1100 sg_set_page(&sg[sg_idx++],
1101 vmalloc_to_page(data), bytes,
1102 offset_in_page(data));
1103
1104 data += bytes;
1105 len -= bytes;
1106 offset = 0;
1107 }
1108 } else {
1109 sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1110 offset_in_page(data));
1111 }
1112 }
1113 smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1114 kfree(nr_entries);
1115 return sg;
1116 }
1117
ksmbd_crypt_message(struct ksmbd_work * work,struct kvec * iov,unsigned int nvec,int enc)1118 int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
1119 unsigned int nvec, int enc)
1120 {
1121 struct ksmbd_conn *conn = work->conn;
1122 struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
1123 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1124 int rc;
1125 struct scatterlist *sg;
1126 u8 sign[SMB2_SIGNATURE_SIZE] = {};
1127 u8 key[SMB3_ENC_DEC_KEY_SIZE];
1128 struct aead_request *req;
1129 char *iv;
1130 unsigned int iv_len;
1131 struct crypto_aead *tfm;
1132 unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1133 struct ksmbd_crypto_ctx *ctx;
1134
1135 rc = ksmbd_get_encryption_key(work,
1136 le64_to_cpu(tr_hdr->SessionId),
1137 enc,
1138 key);
1139 if (rc) {
1140 pr_err("Could not get %scryption key\n", enc ? "en" : "de");
1141 return rc;
1142 }
1143
1144 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1145 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1146 ctx = ksmbd_crypto_ctx_find_gcm();
1147 else
1148 ctx = ksmbd_crypto_ctx_find_ccm();
1149 if (!ctx) {
1150 pr_err("crypto alloc failed\n");
1151 return -ENOMEM;
1152 }
1153
1154 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1155 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1156 tfm = CRYPTO_GCM(ctx);
1157 else
1158 tfm = CRYPTO_CCM(ctx);
1159
1160 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1161 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1162 rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1163 else
1164 rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
1165 if (rc) {
1166 pr_err("Failed to set aead key %d\n", rc);
1167 goto free_ctx;
1168 }
1169
1170 rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1171 if (rc) {
1172 pr_err("Failed to set authsize %d\n", rc);
1173 goto free_ctx;
1174 }
1175
1176 req = aead_request_alloc(tfm, GFP_KERNEL);
1177 if (!req) {
1178 rc = -ENOMEM;
1179 goto free_ctx;
1180 }
1181
1182 if (!enc) {
1183 memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1184 crypt_len += SMB2_SIGNATURE_SIZE;
1185 }
1186
1187 sg = ksmbd_init_sg(iov, nvec, sign);
1188 if (!sg) {
1189 pr_err("Failed to init sg\n");
1190 rc = -ENOMEM;
1191 goto free_req;
1192 }
1193
1194 iv_len = crypto_aead_ivsize(tfm);
1195 iv = kzalloc(iv_len, GFP_KERNEL);
1196 if (!iv) {
1197 rc = -ENOMEM;
1198 goto free_sg;
1199 }
1200
1201 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1202 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1203 memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
1204 } else {
1205 iv[0] = 3;
1206 memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
1207 }
1208
1209 aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1210 aead_request_set_ad(req, assoc_data_len);
1211 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1212
1213 if (enc)
1214 rc = crypto_aead_encrypt(req);
1215 else
1216 rc = crypto_aead_decrypt(req);
1217 if (rc)
1218 goto free_iv;
1219
1220 if (enc)
1221 memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1222
1223 free_iv:
1224 kfree(iv);
1225 free_sg:
1226 kfree(sg);
1227 free_req:
1228 aead_request_free(req);
1229 free_ctx:
1230 ksmbd_release_crypto_ctx(ctx);
1231 return rc;
1232 }
1233