blob: 711f8dec38e1c994a60892d2fc1a97f0c61b2053 [file] [log] [blame]
Namjae Jeone2f34482021-03-16 10:49:09 +09001// 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 "buffer_pool.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 */
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
Namjae Jeone2f34482021-03-16 10:49:09 +090067void ksmbd_copy_gss_neg_header(void *buf)
68{
69 memcpy(buf, NEGOTIATE_GSS_HEADER, AUTH_GSS_LENGTH);
70}
71
72static void
73str_to_key(unsigned char *str, unsigned char *key)
74{
75 int i;
76
77 key[0] = str[0] >> 1;
78 key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
79 key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
80 key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
81 key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
82 key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
83 key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
84 key[7] = str[6] & 0x7F;
85 for (i = 0; i < 8; i++)
86 key[i] = (key[i] << 1);
87}
88
89static int
90smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
91{
92 unsigned char key2[8];
93 struct des_ctx ctx;
94
Namjae Jeone2f34482021-03-16 10:49:09 +090095 if (fips_enabled) {
96 ksmbd_debug(AUTH,
97 "FIPS compliance enabled: DES not permitted\n");
98 return -ENOENT;
99 }
100
Namjae Jeon94096702021-05-26 15:25:40 +0900101 str_to_key(key, key2);
Namjae Jeone2f34482021-03-16 10:49:09 +0900102 des_expand_key(&ctx, key2, DES_KEY_SIZE);
103 des_encrypt(&ctx, out, in);
104 memzero_explicit(&ctx, sizeof(ctx));
105 return 0;
106}
107
Namjae Jeon64b39f42021-03-30 14:25:35 +0900108static int ksmbd_enc_p24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
Namjae Jeone2f34482021-03-16 10:49:09 +0900109{
110 int rc;
111
112 rc = smbhash(p24, c8, p21);
113 if (rc)
114 return rc;
115 rc = smbhash(p24 + 8, c8, p21 + 7);
116 if (rc)
117 return rc;
Namjae Jeonfd43cbb2021-05-26 15:26:33 +0900118 return smbhash(p24 + 16, c8, p21 + 14);
Namjae Jeone2f34482021-03-16 10:49:09 +0900119}
120
121/* produce a md4 message digest from data of length n bytes */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900122static int ksmbd_enc_md4(unsigned char *md4_hash, unsigned char *link_str,
123 int link_len)
Namjae Jeone2f34482021-03-16 10:49:09 +0900124{
125 int rc;
126 struct ksmbd_crypto_ctx *ctx;
127
128 ctx = ksmbd_crypto_ctx_find_md4();
129 if (!ctx) {
130 ksmbd_debug(AUTH, "Crypto md4 allocation error\n");
131 return -EINVAL;
132 }
133
134 rc = crypto_shash_init(CRYPTO_MD4(ctx));
135 if (rc) {
136 ksmbd_debug(AUTH, "Could not init md4 shash\n");
137 goto out;
138 }
139
140 rc = crypto_shash_update(CRYPTO_MD4(ctx), link_str, link_len);
141 if (rc) {
142 ksmbd_debug(AUTH, "Could not update with link_str\n");
143 goto out;
144 }
145
146 rc = crypto_shash_final(CRYPTO_MD4(ctx), md4_hash);
147 if (rc)
148 ksmbd_debug(AUTH, "Could not generate md4 hash\n");
149out:
150 ksmbd_release_crypto_ctx(ctx);
151 return rc;
152}
153
Namjae Jeon64b39f42021-03-30 14:25:35 +0900154static int ksmbd_enc_update_sess_key(unsigned char *md5_hash, char *nonce,
155 char *server_challenge, int len)
Namjae Jeone2f34482021-03-16 10:49:09 +0900156{
157 int rc;
158 struct ksmbd_crypto_ctx *ctx;
159
160 ctx = ksmbd_crypto_ctx_find_md5();
161 if (!ctx) {
162 ksmbd_debug(AUTH, "Crypto md5 allocation error\n");
163 return -EINVAL;
164 }
165
166 rc = crypto_shash_init(CRYPTO_MD5(ctx));
167 if (rc) {
168 ksmbd_debug(AUTH, "Could not init md5 shash\n");
169 goto out;
170 }
171
172 rc = crypto_shash_update(CRYPTO_MD5(ctx), server_challenge, len);
173 if (rc) {
174 ksmbd_debug(AUTH, "Could not update with challenge\n");
175 goto out;
176 }
177
178 rc = crypto_shash_update(CRYPTO_MD5(ctx), nonce, len);
179 if (rc) {
180 ksmbd_debug(AUTH, "Could not update with nonce\n");
181 goto out;
182 }
183
184 rc = crypto_shash_final(CRYPTO_MD5(ctx), md5_hash);
185 if (rc)
186 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
187out:
188 ksmbd_release_crypto_ctx(ctx);
189 return rc;
190}
191
192/**
193 * ksmbd_gen_sess_key() - function to generate session key
194 * @sess: session of connection
195 * @hash: source hash value to be used for find session key
196 * @hmac: source hmac value to be used for finding session key
197 *
198 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900199static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
200 char *hmac)
Namjae Jeone2f34482021-03-16 10:49:09 +0900201{
202 struct ksmbd_crypto_ctx *ctx;
203 int rc = -EINVAL;
204
205 ctx = ksmbd_crypto_ctx_find_hmacmd5();
206 if (!ctx)
207 goto out;
208
209 rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
210 hash,
211 CIFS_HMAC_MD5_HASH_SIZE);
212 if (rc) {
213 ksmbd_debug(AUTH, "hmacmd5 set key fail error %d\n", rc);
214 goto out;
215 }
216
217 rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
218 if (rc) {
219 ksmbd_debug(AUTH, "could not init hmacmd5 error %d\n", rc);
220 goto out;
221 }
222
223 rc = crypto_shash_update(CRYPTO_HMACMD5(ctx),
224 hmac,
225 SMB2_NTLMV2_SESSKEY_SIZE);
226 if (rc) {
227 ksmbd_debug(AUTH, "Could not update with response error %d\n",
228 rc);
229 goto out;
230 }
231
232 rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
233 if (rc) {
234 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
235 rc);
236 goto out;
237 }
238
239out:
240 ksmbd_release_crypto_ctx(ctx);
241 return rc;
242}
243
244static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
Namjae Jeon64b39f42021-03-30 14:25:35 +0900245 char *dname)
Namjae Jeone2f34482021-03-16 10:49:09 +0900246{
247 int ret = -EINVAL, len;
248 wchar_t *domain = NULL;
249 __le16 *uniname = NULL;
250 struct ksmbd_crypto_ctx *ctx;
251
252 ctx = ksmbd_crypto_ctx_find_hmacmd5();
253 if (!ctx) {
254 ksmbd_debug(AUTH, "can't generate ntlmv2 hash\n");
255 goto out;
256 }
257
258 ret = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
259 user_passkey(sess->user),
260 CIFS_ENCPWD_SIZE);
261 if (ret) {
262 ksmbd_debug(AUTH, "Could not set NT Hash as a key\n");
263 goto out;
264 }
265
266 ret = crypto_shash_init(CRYPTO_HMACMD5(ctx));
267 if (ret) {
268 ksmbd_debug(AUTH, "could not init hmacmd5\n");
269 goto out;
270 }
271
272 /* convert user_name to unicode */
273 len = strlen(user_name(sess->user));
274 uniname = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
275 if (!uniname) {
276 ret = -ENOMEM;
277 goto out;
278 }
279
280 if (len) {
281 len = smb_strtoUTF16(uniname, user_name(sess->user), len,
282 sess->conn->local_nls);
283 UniStrupr(uniname);
284 }
285
286 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
287 (char *)uniname,
288 UNICODE_LEN(len));
289 if (ret) {
290 ksmbd_debug(AUTH, "Could not update with user\n");
291 goto out;
292 }
293
294 /* Convert domain name or conn name to unicode and uppercase */
295 len = strlen(dname);
296 domain = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
297 if (!domain) {
298 ret = -ENOMEM;
299 goto out;
300 }
301
302 len = smb_strtoUTF16((__le16 *)domain, dname, len,
303 sess->conn->local_nls);
304
305 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
306 (char *)domain,
307 UNICODE_LEN(len));
308 if (ret) {
309 ksmbd_debug(AUTH, "Could not update with domain\n");
310 goto out;
311 }
312
313 ret = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_hash);
Namjae Jeone2f34482021-03-16 10:49:09 +0900314 if (ret)
315 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
Namjae Jeon7e38ea22021-05-26 15:27:11 +0900316out:
Namjae Jeone2f34482021-03-16 10:49:09 +0900317 kfree(uniname);
318 kfree(domain);
319 ksmbd_release_crypto_ctx(ctx);
320 return ret;
321}
322
323/**
324 * ksmbd_auth_ntlm() - NTLM authentication handler
325 * @sess: session of connection
326 * @pw_buf: NTLM challenge response
327 * @passkey: user password
328 *
329 * Return: 0 on success, error number on error
330 */
331int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf)
332{
333 int rc;
334 unsigned char p21[21];
335 char key[CIFS_AUTH_RESP_SIZE];
336
337 memset(p21, '\0', 21);
338 memcpy(p21, user_passkey(sess->user), CIFS_NTHASH_SIZE);
339 rc = ksmbd_enc_p24(p21, sess->ntlmssp.cryptkey, key);
340 if (rc) {
341 ksmbd_err("password processing failed\n");
342 return rc;
343 }
344
345 ksmbd_enc_md4(sess->sess_key,
346 user_passkey(sess->user),
347 CIFS_SMB1_SESSKEY_SIZE);
348 memcpy(sess->sess_key + CIFS_SMB1_SESSKEY_SIZE, key,
349 CIFS_AUTH_RESP_SIZE);
350 sess->sequence_number = 1;
351
352 if (strncmp(pw_buf, key, CIFS_AUTH_RESP_SIZE) != 0) {
353 ksmbd_debug(AUTH, "ntlmv1 authentication failed\n");
Namjae Jeon4a6b0222021-05-26 15:28:09 +0900354 return -EINVAL;
Namjae Jeon64b39f42021-03-30 14:25:35 +0900355 }
Namjae Jeone2f34482021-03-16 10:49:09 +0900356
Namjae Jeon4a6b0222021-05-26 15:28:09 +0900357 ksmbd_debug(AUTH, "ntlmv1 authentication pass\n");
358 return 0;
Namjae Jeone2f34482021-03-16 10:49:09 +0900359}
360
361/**
362 * ksmbd_auth_ntlmv2() - NTLMv2 authentication handler
363 * @sess: session of connection
364 * @ntlmv2: NTLMv2 challenge response
365 * @blen: NTLMv2 blob length
366 * @domain_name: domain name
367 *
368 * Return: 0 on success, error number on error
369 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900370int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
371 int blen, char *domain_name)
Namjae Jeone2f34482021-03-16 10:49:09 +0900372{
373 char ntlmv2_hash[CIFS_ENCPWD_SIZE];
374 char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
375 struct ksmbd_crypto_ctx *ctx;
376 char *construct = NULL;
377 int rc = -EINVAL, len;
378
379 ctx = ksmbd_crypto_ctx_find_hmacmd5();
380 if (!ctx) {
381 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5 rc %d\n", rc);
382 goto out;
383 }
384
385 rc = calc_ntlmv2_hash(sess, ntlmv2_hash, domain_name);
386 if (rc) {
387 ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
388 goto out;
389 }
390
391 rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
392 ntlmv2_hash,
393 CIFS_HMAC_MD5_HASH_SIZE);
394 if (rc) {
395 ksmbd_debug(AUTH, "Could not set NTLMV2 Hash as a key\n");
396 goto out;
397 }
398
399 rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
400 if (rc) {
401 ksmbd_debug(AUTH, "Could not init hmacmd5\n");
402 goto out;
403 }
404
405 len = CIFS_CRYPTO_KEY_SIZE + blen;
406 construct = kzalloc(len, GFP_KERNEL);
407 if (!construct) {
408 rc = -ENOMEM;
409 goto out;
410 }
411
412 memcpy(construct, sess->ntlmssp.cryptkey, CIFS_CRYPTO_KEY_SIZE);
Namjae Jeon192cc732021-05-26 15:28:48 +0900413 memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
Namjae Jeone2f34482021-03-16 10:49:09 +0900414
415 rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
416 if (rc) {
417 ksmbd_debug(AUTH, "Could not update with response\n");
418 goto out;
419 }
420
421 rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_rsp);
422 if (rc) {
423 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
424 goto out;
425 }
426
427 rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
428 if (rc) {
429 ksmbd_debug(AUTH, "Could not generate sess key\n");
430 goto out;
431 }
432
Namjae Jeonb72802a2021-05-26 15:29:24 +0900433 if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
434 rc = -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +0900435out:
436 ksmbd_release_crypto_ctx(ctx);
437 kfree(construct);
438 return rc;
439}
440
441/**
442 * __ksmbd_auth_ntlmv2() - NTLM2(extended security) authentication handler
443 * @sess: session of connection
444 * @client_nonce: client nonce from LM response.
445 * @ntlm_resp: ntlm response data from client.
446 *
447 * Return: 0 on success, error number on error
448 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900449static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce,
450 char *ntlm_resp)
Namjae Jeone2f34482021-03-16 10:49:09 +0900451{
452 char sess_key[CIFS_SMB1_SESSKEY_SIZE] = {0};
453 int rc;
454 unsigned char p21[21];
455 char key[CIFS_AUTH_RESP_SIZE];
456
457 rc = ksmbd_enc_update_sess_key(sess_key,
458 client_nonce,
459 (char *)sess->ntlmssp.cryptkey, 8);
460 if (rc) {
461 ksmbd_err("password processing failed\n");
462 goto out;
463 }
464
465 memset(p21, '\0', 21);
466 memcpy(p21, user_passkey(sess->user), CIFS_NTHASH_SIZE);
467 rc = ksmbd_enc_p24(p21, sess_key, key);
468 if (rc) {
469 ksmbd_err("password processing failed\n");
470 goto out;
471 }
472
Namjae Jeonb72802a2021-05-26 15:29:24 +0900473 if (memcmp(ntlm_resp, key, CIFS_AUTH_RESP_SIZE) != 0)
474 rc = -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +0900475out:
476 return rc;
477}
478
479/**
480 * ksmbd_decode_ntlmssp_auth_blob() - helper function to construct
481 * authenticate blob
482 * @authblob: authenticate blob source pointer
483 * @usr: user details
484 * @sess: session of connection
485 *
486 * Return: 0 on success, error number on error
487 */
488int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
Namjae Jeon64b39f42021-03-30 14:25:35 +0900489 int blob_len, struct ksmbd_session *sess)
Namjae Jeone2f34482021-03-16 10:49:09 +0900490{
491 char *domain_name;
492 unsigned int lm_off, nt_off;
493 unsigned short nt_len;
494 int ret;
495
496 if (blob_len < sizeof(struct authenticate_message)) {
497 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
498 blob_len);
499 return -EINVAL;
500 }
501
502 if (memcmp(authblob->Signature, "NTLMSSP", 8)) {
503 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
504 authblob->Signature);
505 return -EINVAL;
506 }
507
508 lm_off = le32_to_cpu(authblob->LmChallengeResponse.BufferOffset);
509 nt_off = le32_to_cpu(authblob->NtChallengeResponse.BufferOffset);
510 nt_len = le16_to_cpu(authblob->NtChallengeResponse.Length);
511
512 /* process NTLM authentication */
513 if (nt_len == CIFS_AUTH_RESP_SIZE) {
Namjae Jeon64b39f42021-03-30 14:25:35 +0900514 if (le32_to_cpu(authblob->NegotiateFlags) &
515 NTLMSSP_NEGOTIATE_EXTENDED_SEC)
Namjae Jeone2f34482021-03-16 10:49:09 +0900516 return __ksmbd_auth_ntlmv2(sess, (char *)authblob +
517 lm_off, (char *)authblob + nt_off);
518 else
519 return ksmbd_auth_ntlm(sess, (char *)authblob +
520 nt_off);
521 }
522
523 /* TODO : use domain name that imported from configuration file */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900524 domain_name = smb_strndup_from_utf16((const char *)authblob +
Namjae Jeone2f34482021-03-16 10:49:09 +0900525 le32_to_cpu(authblob->DomainName.BufferOffset),
526 le16_to_cpu(authblob->DomainName.Length), true,
527 sess->conn->local_nls);
528 if (IS_ERR(domain_name))
529 return PTR_ERR(domain_name);
530
531 /* process NTLMv2 authentication */
532 ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
533 domain_name);
534 ret = ksmbd_auth_ntlmv2(sess,
535 (struct ntlmv2_resp *)((char *)authblob + nt_off),
536 nt_len - CIFS_ENCPWD_SIZE,
537 domain_name);
538 kfree(domain_name);
539 return ret;
540}
541
542/**
543 * ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
544 * negotiate blob
545 * @negblob: negotiate blob source pointer
546 * @rsp: response header pointer to be updated
547 * @sess: session of connection
548 *
549 */
550int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
Namjae Jeon64b39f42021-03-30 14:25:35 +0900551 int blob_len, struct ksmbd_session *sess)
Namjae Jeone2f34482021-03-16 10:49:09 +0900552{
553 if (blob_len < sizeof(struct negotiate_message)) {
554 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
555 blob_len);
556 return -EINVAL;
557 }
558
559 if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
560 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
561 negblob->Signature);
562 return -EINVAL;
563 }
564
565 sess->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
566 return 0;
567}
568
569/**
570 * ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
571 * challenge blob
572 * @chgblob: challenge blob source pointer to initialize
573 * @rsp: response header pointer to be updated
574 * @sess: session of connection
575 *
576 */
577unsigned int
578ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
579 struct ksmbd_session *sess)
580{
581 struct target_info *tinfo;
582 wchar_t *name;
583 __u8 *target_name;
584 unsigned int len, flags, blob_off, blob_len, type, target_info_len = 0;
585 int cflags = sess->ntlmssp.client_flags;
586
587 memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
588 chgblob->MessageType = NtLmChallenge;
589
590 flags = NTLMSSP_NEGOTIATE_UNICODE |
591 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
592 NTLMSSP_NEGOTIATE_TARGET_INFO;
593
594 if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
595 flags |= NTLMSSP_NEGOTIATE_SIGN;
596 flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
597 NTLMSSP_NEGOTIATE_56);
598 }
599
600 if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
601 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
602
603 if (cflags & NTLMSSP_REQUEST_TARGET)
604 flags |= NTLMSSP_REQUEST_TARGET;
605
606 if (sess->conn->use_spnego &&
Namjae Jeon64b39f42021-03-30 14:25:35 +0900607 (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
Namjae Jeone2f34482021-03-16 10:49:09 +0900608 flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
609
610 chgblob->NegotiateFlags = cpu_to_le32(flags);
611 len = strlen(ksmbd_netbios_name());
612 name = kmalloc(2 + (len * 2), GFP_KERNEL);
613 if (!name)
614 return -ENOMEM;
615
616 len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
617 sess->conn->local_nls);
618 len = UNICODE_LEN(len);
619
620 blob_off = sizeof(struct challenge_message);
621 blob_len = blob_off + len;
622
623 chgblob->TargetName.Length = cpu_to_le16(len);
624 chgblob->TargetName.MaximumLength = cpu_to_le16(len);
625 chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
626
627 /* Initialize random conn challenge */
628 get_random_bytes(sess->ntlmssp.cryptkey, sizeof(__u64));
629 memcpy(chgblob->Challenge, sess->ntlmssp.cryptkey,
630 CIFS_CRYPTO_KEY_SIZE);
631
632 /* Add Target Information to security buffer */
633 chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
634
635 target_name = (__u8 *)chgblob + blob_off;
636 memcpy(target_name, name, len);
637 tinfo = (struct target_info *)(target_name + len);
638
639 chgblob->TargetInfoArray.Length = 0;
640 /* Add target info list for NetBIOS/DNS settings */
641 for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
642 type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
643 tinfo->Type = cpu_to_le16(type);
644 tinfo->Length = cpu_to_le16(len);
645 memcpy(tinfo->Content, name, len);
646 tinfo = (struct target_info *)((char *)tinfo + 4 + len);
647 target_info_len += 4 + len;
648 }
649
650 /* Add terminator subblock */
651 tinfo->Type = 0;
652 tinfo->Length = 0;
653 target_info_len += 4;
654
655 chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
656 chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
657 blob_len += target_info_len;
658 kfree(name);
659 ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
660 return blob_len;
661}
662
663#ifdef CONFIG_SMB_SERVER_KERBEROS5
Namjae Jeon64b39f42021-03-30 14:25:35 +0900664int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
665 int in_len, char *out_blob, int *out_len)
Namjae Jeone2f34482021-03-16 10:49:09 +0900666{
667 struct ksmbd_spnego_authen_response *resp;
668 struct ksmbd_user *user = NULL;
669 int retval;
670
671 resp = ksmbd_ipc_spnego_authen_request(in_blob, in_len);
672 if (!resp) {
673 ksmbd_debug(AUTH, "SPNEGO_AUTHEN_REQUEST failure\n");
674 return -EINVAL;
675 }
676
677 if (!(resp->login_response.status & KSMBD_USER_FLAG_OK)) {
678 ksmbd_debug(AUTH, "krb5 authentication failure\n");
679 retval = -EPERM;
680 goto out;
681 }
682
683 if (*out_len <= resp->spnego_blob_len) {
684 ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
685 *out_len, resp->spnego_blob_len);
686 retval = -EINVAL;
687 goto out;
688 }
689
690 if (resp->session_key_len > sizeof(sess->sess_key)) {
691 ksmbd_debug(AUTH, "session key is too long\n");
692 retval = -EINVAL;
693 goto out;
694 }
695
696 user = ksmbd_alloc_user(&resp->login_response);
697 if (!user) {
698 ksmbd_debug(AUTH, "login failure\n");
699 retval = -ENOMEM;
700 goto out;
701 }
702 sess->user = user;
703
704 memcpy(sess->sess_key, resp->payload, resp->session_key_len);
705 memcpy(out_blob, resp->payload + resp->session_key_len,
706 resp->spnego_blob_len);
707 *out_len = resp->spnego_blob_len;
708 retval = 0;
709out:
Namjae Jeon79f6b112021-04-02 12:47:14 +0900710 kvfree(resp);
Namjae Jeone2f34482021-03-16 10:49:09 +0900711 return retval;
712}
713#else
Namjae Jeon64b39f42021-03-30 14:25:35 +0900714int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
715 int in_len, char *out_blob, int *out_len)
Namjae Jeone2f34482021-03-16 10:49:09 +0900716{
717 return -EOPNOTSUPP;
718}
719#endif
720
721/**
722 * ksmbd_sign_smb2_pdu() - function to generate packet signing
723 * @conn: connection
724 * @key: signing key
725 * @iov: buffer iov array
726 * @n_vec: number of iovecs
727 * @sig: signature value generated for client request packet
728 *
729 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900730int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
731 int n_vec, char *sig)
Namjae Jeone2f34482021-03-16 10:49:09 +0900732{
733 struct ksmbd_crypto_ctx *ctx;
734 int rc = -EINVAL;
735 int i;
736
737 ctx = ksmbd_crypto_ctx_find_hmacsha256();
738 if (!ctx) {
739 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5 rc %d\n", rc);
740 goto out;
741 }
742
743 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
744 key,
745 SMB2_NTLMV2_SESSKEY_SIZE);
746 if (rc)
747 goto out;
748
749 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
750 if (rc) {
751 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
752 goto out;
753 }
754
755 for (i = 0; i < n_vec; i++) {
756 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
757 iov[i].iov_base,
758 iov[i].iov_len);
759 if (rc) {
760 ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
761 goto out;
762 }
763 }
764
765 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
766 if (rc)
767 ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
768out:
769 ksmbd_release_crypto_ctx(ctx);
770 return rc;
771}
772
773/**
774 * ksmbd_sign_smb3_pdu() - function to generate packet signing
775 * @conn: connection
776 * @key: signing key
777 * @iov: buffer iov array
778 * @n_vec: number of iovecs
779 * @sig: signature value generated for client request packet
780 *
781 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900782int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
783 int n_vec, char *sig)
Namjae Jeone2f34482021-03-16 10:49:09 +0900784{
785 struct ksmbd_crypto_ctx *ctx;
786 int rc = -EINVAL;
787 int i;
788
789 ctx = ksmbd_crypto_ctx_find_cmacaes();
790 if (!ctx) {
791 ksmbd_debug(AUTH, "could not crypto alloc cmac rc %d\n", rc);
792 goto out;
793 }
794
795 rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
796 key,
797 SMB2_CMACAES_SIZE);
798 if (rc)
799 goto out;
800
801 rc = crypto_shash_init(CRYPTO_CMACAES(ctx));
802 if (rc) {
803 ksmbd_debug(AUTH, "cmaces init error %d\n", rc);
804 goto out;
805 }
806
807 for (i = 0; i < n_vec; i++) {
808 rc = crypto_shash_update(CRYPTO_CMACAES(ctx),
809 iov[i].iov_base,
810 iov[i].iov_len);
811 if (rc) {
812 ksmbd_debug(AUTH, "cmaces update error %d\n", rc);
813 goto out;
814 }
815 }
816
817 rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig);
818 if (rc)
819 ksmbd_debug(AUTH, "cmaces generation error %d\n", rc);
820out:
821 ksmbd_release_crypto_ctx(ctx);
822 return rc;
823}
824
825struct derivation {
826 struct kvec label;
827 struct kvec context;
828 bool binding;
829};
830
831static int generate_key(struct ksmbd_session *sess, struct kvec label,
Namjae Jeon64b39f42021-03-30 14:25:35 +0900832 struct kvec context, __u8 *key, unsigned int key_size)
Namjae Jeone2f34482021-03-16 10:49:09 +0900833{
834 unsigned char zero = 0x0;
835 __u8 i[4] = {0, 0, 0, 1};
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900836 __u8 L128[4] = {0, 0, 0, 128};
837 __u8 L256[4] = {0, 0, 1, 0};
Namjae Jeone2f34482021-03-16 10:49:09 +0900838 int rc = -EINVAL;
839 unsigned char prfhash[SMB2_HMACSHA256_SIZE];
840 unsigned char *hashptr = prfhash;
841 struct ksmbd_crypto_ctx *ctx;
842
843 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
844 memset(key, 0x0, key_size);
845
846 ctx = ksmbd_crypto_ctx_find_hmacsha256();
847 if (!ctx) {
848 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5 rc %d\n", rc);
849 goto smb3signkey_ret;
850 }
851
852 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
853 sess->sess_key,
854 SMB2_NTLMV2_SESSKEY_SIZE);
855 if (rc)
856 goto smb3signkey_ret;
857
858 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
859 if (rc) {
860 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
861 goto smb3signkey_ret;
862 }
863
864 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
865 if (rc) {
866 ksmbd_debug(AUTH, "could not update with n\n");
867 goto smb3signkey_ret;
868 }
869
870 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
871 label.iov_base,
872 label.iov_len);
873 if (rc) {
874 ksmbd_debug(AUTH, "could not update with label\n");
875 goto smb3signkey_ret;
876 }
877
878 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
879 if (rc) {
880 ksmbd_debug(AUTH, "could not update with zero\n");
881 goto smb3signkey_ret;
882 }
883
884 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
885 context.iov_base,
886 context.iov_len);
887 if (rc) {
888 ksmbd_debug(AUTH, "could not update with context\n");
889 goto smb3signkey_ret;
890 }
891
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900892 if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
893 sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
894 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
895 else
896 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
Namjae Jeone2f34482021-03-16 10:49:09 +0900897 if (rc) {
898 ksmbd_debug(AUTH, "could not update with L\n");
899 goto smb3signkey_ret;
900 }
901
902 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
903 if (rc) {
904 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
905 rc);
906 goto smb3signkey_ret;
907 }
908
909 memcpy(key, hashptr, key_size);
910
911smb3signkey_ret:
912 ksmbd_release_crypto_ctx(ctx);
913 return rc;
914}
915
916static int generate_smb3signingkey(struct ksmbd_session *sess,
Namjae Jeon64b39f42021-03-30 14:25:35 +0900917 const struct derivation *signing)
Namjae Jeone2f34482021-03-16 10:49:09 +0900918{
919 int rc;
920 struct channel *chann;
921 char *key;
922
923 chann = lookup_chann_list(sess);
924 if (!chann)
925 return 0;
926
927 if (sess->conn->dialect >= SMB30_PROT_ID && signing->binding)
928 key = chann->smb3signingkey;
929 else
930 key = sess->smb3signingkey;
931
932 rc = generate_key(sess, signing->label, signing->context, key,
933 SMB3_SIGN_KEY_SIZE);
934 if (rc)
935 return rc;
936
937 if (!(sess->conn->dialect >= SMB30_PROT_ID && signing->binding))
938 memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
939
940 ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
941 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
942 ksmbd_debug(AUTH, "Session Key %*ph\n",
943 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
944 ksmbd_debug(AUTH, "Signing Key %*ph\n",
945 SMB3_SIGN_KEY_SIZE, key);
Namjae Jeon876edcc2021-05-26 15:30:04 +0900946 return 0;
Namjae Jeone2f34482021-03-16 10:49:09 +0900947}
948
949int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess)
950{
951 struct derivation d;
952
953 d.label.iov_base = "SMB2AESCMAC";
954 d.label.iov_len = 12;
955 d.context.iov_base = "SmbSign";
956 d.context.iov_len = 8;
957 d.binding = false;
958
959 return generate_smb3signingkey(sess, &d);
960}
961
962int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess)
963{
964 struct derivation d;
965
966 d.label.iov_base = "SMBSigningKey";
967 d.label.iov_len = 14;
968 d.context.iov_base = sess->Preauth_HashValue;
969 d.context.iov_len = 64;
970 d.binding = false;
971
972 return generate_smb3signingkey(sess, &d);
973}
974
975struct derivation_twin {
976 struct derivation encryption;
977 struct derivation decryption;
978};
979
980static int generate_smb3encryptionkey(struct ksmbd_session *sess,
Namjae Jeon64b39f42021-03-30 14:25:35 +0900981 const struct derivation_twin *ptwin)
Namjae Jeone2f34482021-03-16 10:49:09 +0900982{
983 int rc;
984
985 rc = generate_key(sess, ptwin->encryption.label,
986 ptwin->encryption.context, sess->smb3encryptionkey,
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900987 SMB3_ENC_DEC_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900988 if (rc)
989 return rc;
990
991 rc = generate_key(sess, ptwin->decryption.label,
992 ptwin->decryption.context,
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900993 sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900994 if (rc)
995 return rc;
996
997 ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900998 ksmbd_debug(AUTH, "Cipher type %d\n", sess->conn->cipher_type);
Namjae Jeone2f34482021-03-16 10:49:09 +0900999 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
1000 ksmbd_debug(AUTH, "Session Key %*ph\n",
1001 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001002 if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1003 sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1004 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
1005 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
1006 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
1007 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
1008 } else {
1009 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
1010 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
1011 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
1012 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
1013 }
Namjae Jeon876edcc2021-05-26 15:30:04 +09001014 return 0;
Namjae Jeone2f34482021-03-16 10:49:09 +09001015}
1016
1017int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess)
1018{
1019 struct derivation_twin twin;
1020 struct derivation *d;
1021
1022 d = &twin.encryption;
1023 d->label.iov_base = "SMB2AESCCM";
1024 d->label.iov_len = 11;
1025 d->context.iov_base = "ServerOut";
1026 d->context.iov_len = 10;
1027
1028 d = &twin.decryption;
1029 d->label.iov_base = "SMB2AESCCM";
1030 d->label.iov_len = 11;
1031 d->context.iov_base = "ServerIn ";
1032 d->context.iov_len = 10;
1033
1034 return generate_smb3encryptionkey(sess, &twin);
1035}
1036
1037int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
1038{
1039 struct derivation_twin twin;
1040 struct derivation *d;
1041
1042 d = &twin.encryption;
1043 d->label.iov_base = "SMBS2CCipherKey";
1044 d->label.iov_len = 16;
1045 d->context.iov_base = sess->Preauth_HashValue;
1046 d->context.iov_len = 64;
1047
1048 d = &twin.decryption;
1049 d->label.iov_base = "SMBC2SCipherKey";
1050 d->label.iov_len = 16;
1051 d->context.iov_base = sess->Preauth_HashValue;
1052 d->context.iov_len = 64;
1053
1054 return generate_smb3encryptionkey(sess, &twin);
1055}
1056
Namjae Jeon64b39f42021-03-30 14:25:35 +09001057int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
1058 __u8 *pi_hash)
Namjae Jeone2f34482021-03-16 10:49:09 +09001059{
1060 int rc = -1;
1061 struct smb2_hdr *rcv_hdr = (struct smb2_hdr *)buf;
1062 char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
1063 int msg_size = be32_to_cpu(rcv_hdr->smb2_buf_length);
1064 struct ksmbd_crypto_ctx *ctx = NULL;
1065
1066 if (conn->preauth_info->Preauth_HashId ==
Namjae Jeon64b39f42021-03-30 14:25:35 +09001067 SMB2_PREAUTH_INTEGRITY_SHA512) {
Namjae Jeone2f34482021-03-16 10:49:09 +09001068 ctx = ksmbd_crypto_ctx_find_sha512();
1069 if (!ctx) {
1070 ksmbd_debug(AUTH, "could not alloc sha512 rc %d\n", rc);
1071 goto out;
1072 }
Namjae Jeon64b39f42021-03-30 14:25:35 +09001073 } else {
Namjae Jeone2f34482021-03-16 10:49:09 +09001074 goto out;
Namjae Jeon64b39f42021-03-30 14:25:35 +09001075 }
Namjae Jeone2f34482021-03-16 10:49:09 +09001076
1077 rc = crypto_shash_init(CRYPTO_SHA512(ctx));
1078 if (rc) {
1079 ksmbd_debug(AUTH, "could not init shashn");
1080 goto out;
1081 }
1082
1083 rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
1084 if (rc) {
1085 ksmbd_debug(AUTH, "could not update with n\n");
1086 goto out;
1087 }
1088
1089 rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
1090 if (rc) {
1091 ksmbd_debug(AUTH, "could not update with n\n");
1092 goto out;
1093 }
1094
1095 rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
1096 if (rc) {
1097 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
1098 goto out;
1099 }
1100out:
1101 ksmbd_release_crypto_ctx(ctx);
1102 return rc;
1103}
1104
1105int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
1106 __u8 *pi_hash)
1107{
1108 int rc = -1;
1109 struct ksmbd_crypto_ctx *ctx = NULL;
1110
1111 ctx = ksmbd_crypto_ctx_find_sha256();
1112 if (!ctx) {
1113 ksmbd_debug(AUTH, "could not alloc sha256 rc %d\n", rc);
1114 goto out;
1115 }
1116
1117 rc = crypto_shash_init(CRYPTO_SHA256(ctx));
1118 if (rc) {
1119 ksmbd_debug(AUTH, "could not init shashn");
1120 goto out;
1121 }
1122
1123 rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
1124 if (rc) {
1125 ksmbd_debug(AUTH, "could not update with n\n");
1126 goto out;
1127 }
1128
1129 rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
1130 if (rc) {
1131 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
1132 goto out;
1133 }
1134out:
1135 ksmbd_release_crypto_ctx(ctx);
1136 return rc;
1137}
1138
Namjae Jeon64b39f42021-03-30 14:25:35 +09001139static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
1140 int enc, u8 *key)
Namjae Jeone2f34482021-03-16 10:49:09 +09001141{
1142 struct ksmbd_session *sess;
1143 u8 *ses_enc_key;
1144
1145 sess = ksmbd_session_lookup(conn, ses_id);
1146 if (!sess)
Namjae Jeon522dcc72021-05-26 15:30:50 +09001147 return -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +09001148
1149 ses_enc_key = enc ? sess->smb3encryptionkey :
1150 sess->smb3decryptionkey;
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001151 memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +09001152
1153 return 0;
1154}
1155
1156static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
1157 unsigned int buflen)
1158{
1159 void *addr;
1160
1161 if (is_vmalloc_addr(buf))
1162 addr = vmalloc_to_page(buf);
1163 else
1164 addr = virt_to_page(buf);
1165 sg_set_page(sg, addr, buflen, offset_in_page(buf));
1166}
1167
Namjae Jeon64b39f42021-03-30 14:25:35 +09001168static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
1169 u8 *sign)
Namjae Jeone2f34482021-03-16 10:49:09 +09001170{
1171 struct scatterlist *sg;
1172 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
1173 int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0;
1174
Namjae Jeon41a78482021-05-26 15:31:37 +09001175 if (!nvec)
1176 return NULL;
1177
Namjae Jeone2f34482021-03-16 10:49:09 +09001178 for (i = 0; i < nvec - 1; i++) {
1179 unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
1180
1181 if (is_vmalloc_addr(iov[i + 1].iov_base)) {
1182 nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
1183 PAGE_SIZE - 1) >> PAGE_SHIFT) -
1184 (kaddr >> PAGE_SHIFT);
Namjae Jeon64b39f42021-03-30 14:25:35 +09001185 } else {
Namjae Jeone2f34482021-03-16 10:49:09 +09001186 nr_entries[i]++;
Namjae Jeon64b39f42021-03-30 14:25:35 +09001187 }
Namjae Jeone2f34482021-03-16 10:49:09 +09001188 total_entries += nr_entries[i];
1189 }
1190
1191 /* Add two entries for transform header and signature */
1192 total_entries += 2;
1193
1194 sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
1195 if (!sg)
1196 return NULL;
1197
1198 sg_init_table(sg, total_entries);
1199 smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1200 for (i = 0; i < nvec - 1; i++) {
1201 void *data = iov[i + 1].iov_base;
1202 int len = iov[i + 1].iov_len;
1203
1204 if (is_vmalloc_addr(data)) {
1205 int j, offset = offset_in_page(data);
1206
1207 for (j = 0; j < nr_entries[i]; j++) {
1208 unsigned int bytes = PAGE_SIZE - offset;
1209
Namjae Jeon08591cc2021-05-26 15:32:26 +09001210 if (!len)
Namjae Jeone2f34482021-03-16 10:49:09 +09001211 break;
1212
1213 if (bytes > len)
1214 bytes = len;
1215
1216 sg_set_page(&sg[sg_idx++],
1217 vmalloc_to_page(data), bytes,
1218 offset_in_page(data));
1219
1220 data += bytes;
1221 len -= bytes;
1222 offset = 0;
1223 }
1224 } else {
1225 sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1226 offset_in_page(data));
1227 }
Namjae Jeone2f34482021-03-16 10:49:09 +09001228 }
1229 smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1230 return sg;
1231}
1232
Namjae Jeon64b39f42021-03-30 14:25:35 +09001233int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
1234 unsigned int nvec, int enc)
Namjae Jeone2f34482021-03-16 10:49:09 +09001235{
1236 struct smb2_transform_hdr *tr_hdr =
1237 (struct smb2_transform_hdr *)iov[0].iov_base;
1238 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
Namjae Jeon03f1c3d2021-05-26 15:34:37 +09001239 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +09001240 struct scatterlist *sg;
1241 u8 sign[SMB2_SIGNATURE_SIZE] = {};
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001242 u8 key[SMB3_ENC_DEC_KEY_SIZE];
Namjae Jeone2f34482021-03-16 10:49:09 +09001243 struct aead_request *req;
1244 char *iv;
1245 unsigned int iv_len;
1246 struct crypto_aead *tfm;
1247 unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1248 struct ksmbd_crypto_ctx *ctx;
1249
1250 rc = ksmbd_get_encryption_key(conn,
1251 le64_to_cpu(tr_hdr->SessionId),
1252 enc,
1253 key);
1254 if (rc) {
1255 ksmbd_err("Could not get %scryption key\n", enc ? "en" : "de");
1256 return 0;
1257 }
1258
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001259 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1260 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
Namjae Jeone2f34482021-03-16 10:49:09 +09001261 ctx = ksmbd_crypto_ctx_find_gcm();
1262 else
1263 ctx = ksmbd_crypto_ctx_find_ccm();
1264 if (!ctx) {
1265 ksmbd_err("crypto alloc failed\n");
1266 return -EINVAL;
1267 }
1268
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001269 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1270 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
Namjae Jeone2f34482021-03-16 10:49:09 +09001271 tfm = CRYPTO_GCM(ctx);
1272 else
1273 tfm = CRYPTO_CCM(ctx);
1274
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001275 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1276 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1277 rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1278 else
1279 rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +09001280 if (rc) {
1281 ksmbd_err("Failed to set aead key %d\n", rc);
1282 goto free_ctx;
1283 }
1284
1285 rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1286 if (rc) {
1287 ksmbd_err("Failed to set authsize %d\n", rc);
1288 goto free_ctx;
1289 }
1290
1291 req = aead_request_alloc(tfm, GFP_KERNEL);
1292 if (!req) {
1293 ksmbd_err("Failed to alloc aead request\n");
1294 rc = -ENOMEM;
1295 goto free_ctx;
1296 }
1297
1298 if (!enc) {
1299 memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1300 crypt_len += SMB2_SIGNATURE_SIZE;
1301 }
1302
1303 sg = ksmbd_init_sg(iov, nvec, sign);
1304 if (!sg) {
1305 ksmbd_err("Failed to init sg\n");
1306 rc = -ENOMEM;
1307 goto free_req;
1308 }
1309
1310 iv_len = crypto_aead_ivsize(tfm);
1311 iv = kzalloc(iv_len, GFP_KERNEL);
1312 if (!iv) {
1313 ksmbd_err("Failed to alloc IV\n");
1314 rc = -ENOMEM;
1315 goto free_sg;
1316 }
1317
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001318 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1319 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1320 memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
Namjae Jeon64b39f42021-03-30 14:25:35 +09001321 } else {
Namjae Jeone2f34482021-03-16 10:49:09 +09001322 iv[0] = 3;
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001323 memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
Namjae Jeone2f34482021-03-16 10:49:09 +09001324 }
1325
1326 aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1327 aead_request_set_ad(req, assoc_data_len);
1328 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1329
1330 if (enc)
1331 rc = crypto_aead_encrypt(req);
1332 else
1333 rc = crypto_aead_decrypt(req);
1334 if (!rc && enc)
1335 memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1336
1337 kfree(iv);
1338free_sg:
1339 kfree(sg);
1340free_req:
1341 kfree(req);
1342free_ctx:
1343 ksmbd_release_crypto_ctx(ctx);
1344 return rc;
1345}