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