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