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