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_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 memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
1020
1021 return 0;
1022 }
1023
smb2_sg_set_buf(struct scatterlist * sg,const void * buf,unsigned int buflen)1024 static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
1025 unsigned int buflen)
1026 {
1027 void *addr;
1028
1029 if (is_vmalloc_addr(buf))
1030 addr = vmalloc_to_page(buf);
1031 else
1032 addr = virt_to_page(buf);
1033 sg_set_page(sg, addr, buflen, offset_in_page(buf));
1034 }
1035
ksmbd_init_sg(struct kvec * iov,unsigned int nvec,u8 * sign)1036 static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
1037 u8 *sign)
1038 {
1039 struct scatterlist *sg;
1040 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1041 int i, *nr_entries, total_entries = 0, sg_idx = 0;
1042
1043 if (!nvec)
1044 return NULL;
1045
1046 nr_entries = kcalloc(nvec, sizeof(int), GFP_KERNEL);
1047 if (!nr_entries)
1048 return NULL;
1049
1050 for (i = 0; i < nvec - 1; i++) {
1051 unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
1052
1053 if (is_vmalloc_addr(iov[i + 1].iov_base)) {
1054 nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
1055 PAGE_SIZE - 1) >> PAGE_SHIFT) -
1056 (kaddr >> PAGE_SHIFT);
1057 } else {
1058 nr_entries[i]++;
1059 }
1060 total_entries += nr_entries[i];
1061 }
1062
1063 /* Add two entries for transform header and signature */
1064 total_entries += 2;
1065
1066 sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
1067 if (!sg) {
1068 kfree(nr_entries);
1069 return NULL;
1070 }
1071
1072 sg_init_table(sg, total_entries);
1073 smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1074 for (i = 0; i < nvec - 1; i++) {
1075 void *data = iov[i + 1].iov_base;
1076 int len = iov[i + 1].iov_len;
1077
1078 if (is_vmalloc_addr(data)) {
1079 int j, offset = offset_in_page(data);
1080
1081 for (j = 0; j < nr_entries[i]; j++) {
1082 unsigned int bytes = PAGE_SIZE - offset;
1083
1084 if (!len)
1085 break;
1086
1087 if (bytes > len)
1088 bytes = len;
1089
1090 sg_set_page(&sg[sg_idx++],
1091 vmalloc_to_page(data), bytes,
1092 offset_in_page(data));
1093
1094 data += bytes;
1095 len -= bytes;
1096 offset = 0;
1097 }
1098 } else {
1099 sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1100 offset_in_page(data));
1101 }
1102 }
1103 smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1104 kfree(nr_entries);
1105 return sg;
1106 }
1107
ksmbd_crypt_message(struct ksmbd_work * work,struct kvec * iov,unsigned int nvec,int enc)1108 int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
1109 unsigned int nvec, int enc)
1110 {
1111 struct ksmbd_conn *conn = work->conn;
1112 struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
1113 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1114 int rc;
1115 struct scatterlist *sg;
1116 u8 sign[SMB2_SIGNATURE_SIZE] = {};
1117 u8 key[SMB3_ENC_DEC_KEY_SIZE];
1118 struct aead_request *req;
1119 char *iv;
1120 unsigned int iv_len;
1121 struct crypto_aead *tfm;
1122 unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1123 struct ksmbd_crypto_ctx *ctx;
1124
1125 rc = ksmbd_get_encryption_key(work,
1126 le64_to_cpu(tr_hdr->SessionId),
1127 enc,
1128 key);
1129 if (rc) {
1130 pr_err("Could not get %scryption key\n", enc ? "en" : "de");
1131 return rc;
1132 }
1133
1134 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1135 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1136 ctx = ksmbd_crypto_ctx_find_gcm();
1137 else
1138 ctx = ksmbd_crypto_ctx_find_ccm();
1139 if (!ctx) {
1140 pr_err("crypto alloc failed\n");
1141 return -ENOMEM;
1142 }
1143
1144 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1145 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1146 tfm = CRYPTO_GCM(ctx);
1147 else
1148 tfm = CRYPTO_CCM(ctx);
1149
1150 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1151 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1152 rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1153 else
1154 rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
1155 if (rc) {
1156 pr_err("Failed to set aead key %d\n", rc);
1157 goto free_ctx;
1158 }
1159
1160 rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1161 if (rc) {
1162 pr_err("Failed to set authsize %d\n", rc);
1163 goto free_ctx;
1164 }
1165
1166 req = aead_request_alloc(tfm, GFP_KERNEL);
1167 if (!req) {
1168 rc = -ENOMEM;
1169 goto free_ctx;
1170 }
1171
1172 if (!enc) {
1173 memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1174 crypt_len += SMB2_SIGNATURE_SIZE;
1175 }
1176
1177 sg = ksmbd_init_sg(iov, nvec, sign);
1178 if (!sg) {
1179 pr_err("Failed to init sg\n");
1180 rc = -ENOMEM;
1181 goto free_req;
1182 }
1183
1184 iv_len = crypto_aead_ivsize(tfm);
1185 iv = kzalloc(iv_len, GFP_KERNEL);
1186 if (!iv) {
1187 rc = -ENOMEM;
1188 goto free_sg;
1189 }
1190
1191 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1192 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1193 memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
1194 } else {
1195 iv[0] = 3;
1196 memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
1197 }
1198
1199 aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1200 aead_request_set_ad(req, assoc_data_len);
1201 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1202
1203 if (enc)
1204 rc = crypto_aead_encrypt(req);
1205 else
1206 rc = crypto_aead_decrypt(req);
1207 if (rc)
1208 goto free_iv;
1209
1210 if (enc)
1211 memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1212
1213 free_iv:
1214 kfree(iv);
1215 free_sg:
1216 kfree(sg);
1217 free_req:
1218 kfree(req);
1219 free_ctx:
1220 ksmbd_release_crypto_ctx(ctx);
1221 return rc;
1222 }
1223