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