blob: 8c80f918c8d7a632fd9f2b32e36c2452d2066cea [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");
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900131 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900132 }
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");
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900163 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900164 }
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;
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900203 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +0900204
205 ctx = ksmbd_crypto_ctx_find_hmacmd5();
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900206 if (!ctx) {
207 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
208 return -ENOMEM;
209 }
Namjae Jeone2f34482021-03-16 10:49:09 +0900210
211 rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
212 hash,
213 CIFS_HMAC_MD5_HASH_SIZE);
214 if (rc) {
215 ksmbd_debug(AUTH, "hmacmd5 set key fail error %d\n", rc);
216 goto out;
217 }
218
219 rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
220 if (rc) {
221 ksmbd_debug(AUTH, "could not init hmacmd5 error %d\n", rc);
222 goto out;
223 }
224
225 rc = crypto_shash_update(CRYPTO_HMACMD5(ctx),
226 hmac,
227 SMB2_NTLMV2_SESSKEY_SIZE);
228 if (rc) {
229 ksmbd_debug(AUTH, "Could not update with response error %d\n",
230 rc);
231 goto out;
232 }
233
234 rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
235 if (rc) {
236 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
237 rc);
238 goto out;
239 }
240
241out:
242 ksmbd_release_crypto_ctx(ctx);
243 return rc;
244}
245
246static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
Namjae Jeon64b39f42021-03-30 14:25:35 +0900247 char *dname)
Namjae Jeone2f34482021-03-16 10:49:09 +0900248{
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900249 int ret, len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900250 wchar_t *domain = NULL;
251 __le16 *uniname = NULL;
252 struct ksmbd_crypto_ctx *ctx;
253
254 ctx = ksmbd_crypto_ctx_find_hmacmd5();
255 if (!ctx) {
256 ksmbd_debug(AUTH, "can't generate ntlmv2 hash\n");
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900257 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900258 }
259
260 ret = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
261 user_passkey(sess->user),
262 CIFS_ENCPWD_SIZE);
263 if (ret) {
264 ksmbd_debug(AUTH, "Could not set NT Hash as a key\n");
265 goto out;
266 }
267
268 ret = crypto_shash_init(CRYPTO_HMACMD5(ctx));
269 if (ret) {
270 ksmbd_debug(AUTH, "could not init hmacmd5\n");
271 goto out;
272 }
273
274 /* convert user_name to unicode */
275 len = strlen(user_name(sess->user));
276 uniname = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
277 if (!uniname) {
278 ret = -ENOMEM;
279 goto out;
280 }
281
282 if (len) {
283 len = smb_strtoUTF16(uniname, user_name(sess->user), len,
284 sess->conn->local_nls);
285 UniStrupr(uniname);
286 }
287
288 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
289 (char *)uniname,
290 UNICODE_LEN(len));
291 if (ret) {
292 ksmbd_debug(AUTH, "Could not update with user\n");
293 goto out;
294 }
295
296 /* Convert domain name or conn name to unicode and uppercase */
297 len = strlen(dname);
298 domain = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
299 if (!domain) {
300 ret = -ENOMEM;
301 goto out;
302 }
303
304 len = smb_strtoUTF16((__le16 *)domain, dname, len,
305 sess->conn->local_nls);
306
307 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
308 (char *)domain,
309 UNICODE_LEN(len));
310 if (ret) {
311 ksmbd_debug(AUTH, "Could not update with domain\n");
312 goto out;
313 }
314
315 ret = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_hash);
Namjae Jeone2f34482021-03-16 10:49:09 +0900316 if (ret)
317 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
Namjae Jeon7e38ea22021-05-26 15:27:11 +0900318out:
Namjae Jeone2f34482021-03-16 10:49:09 +0900319 kfree(uniname);
320 kfree(domain);
321 ksmbd_release_crypto_ctx(ctx);
322 return ret;
323}
324
325/**
326 * ksmbd_auth_ntlm() - NTLM authentication handler
327 * @sess: session of connection
328 * @pw_buf: NTLM challenge response
329 * @passkey: user password
330 *
331 * Return: 0 on success, error number on error
332 */
333int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf)
334{
335 int rc;
336 unsigned char p21[21];
337 char key[CIFS_AUTH_RESP_SIZE];
338
339 memset(p21, '\0', 21);
340 memcpy(p21, user_passkey(sess->user), CIFS_NTHASH_SIZE);
341 rc = ksmbd_enc_p24(p21, sess->ntlmssp.cryptkey, key);
342 if (rc) {
343 ksmbd_err("password processing failed\n");
344 return rc;
345 }
346
347 ksmbd_enc_md4(sess->sess_key,
348 user_passkey(sess->user),
349 CIFS_SMB1_SESSKEY_SIZE);
350 memcpy(sess->sess_key + CIFS_SMB1_SESSKEY_SIZE, key,
351 CIFS_AUTH_RESP_SIZE);
352 sess->sequence_number = 1;
353
354 if (strncmp(pw_buf, key, CIFS_AUTH_RESP_SIZE) != 0) {
355 ksmbd_debug(AUTH, "ntlmv1 authentication failed\n");
Namjae Jeon4a6b0222021-05-26 15:28:09 +0900356 return -EINVAL;
Namjae Jeon64b39f42021-03-30 14:25:35 +0900357 }
Namjae Jeone2f34482021-03-16 10:49:09 +0900358
Namjae Jeon4a6b0222021-05-26 15:28:09 +0900359 ksmbd_debug(AUTH, "ntlmv1 authentication pass\n");
360 return 0;
Namjae Jeone2f34482021-03-16 10:49:09 +0900361}
362
363/**
364 * ksmbd_auth_ntlmv2() - NTLMv2 authentication handler
365 * @sess: session of connection
366 * @ntlmv2: NTLMv2 challenge response
367 * @blen: NTLMv2 blob length
368 * @domain_name: domain name
369 *
370 * Return: 0 on success, error number on error
371 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900372int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
373 int blen, char *domain_name)
Namjae Jeone2f34482021-03-16 10:49:09 +0900374{
375 char ntlmv2_hash[CIFS_ENCPWD_SIZE];
376 char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
377 struct ksmbd_crypto_ctx *ctx;
378 char *construct = NULL;
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900379 int rc, len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900380
381 ctx = ksmbd_crypto_ctx_find_hmacmd5();
382 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900383 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
384 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900385 }
386
387 rc = calc_ntlmv2_hash(sess, ntlmv2_hash, domain_name);
388 if (rc) {
389 ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
390 goto out;
391 }
392
393 rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
394 ntlmv2_hash,
395 CIFS_HMAC_MD5_HASH_SIZE);
396 if (rc) {
397 ksmbd_debug(AUTH, "Could not set NTLMV2 Hash as a key\n");
398 goto out;
399 }
400
401 rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
402 if (rc) {
403 ksmbd_debug(AUTH, "Could not init hmacmd5\n");
404 goto out;
405 }
406
407 len = CIFS_CRYPTO_KEY_SIZE + blen;
408 construct = kzalloc(len, GFP_KERNEL);
409 if (!construct) {
410 rc = -ENOMEM;
411 goto out;
412 }
413
414 memcpy(construct, sess->ntlmssp.cryptkey, CIFS_CRYPTO_KEY_SIZE);
Namjae Jeon192cc732021-05-26 15:28:48 +0900415 memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
Namjae Jeone2f34482021-03-16 10:49:09 +0900416
417 rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
418 if (rc) {
419 ksmbd_debug(AUTH, "Could not update with response\n");
420 goto out;
421 }
422
423 rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_rsp);
424 if (rc) {
425 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
426 goto out;
427 }
428
429 rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
430 if (rc) {
431 ksmbd_debug(AUTH, "Could not generate sess key\n");
432 goto out;
433 }
434
Namjae Jeonb72802a2021-05-26 15:29:24 +0900435 if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
436 rc = -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +0900437out:
438 ksmbd_release_crypto_ctx(ctx);
439 kfree(construct);
440 return rc;
441}
442
443/**
444 * __ksmbd_auth_ntlmv2() - NTLM2(extended security) authentication handler
445 * @sess: session of connection
446 * @client_nonce: client nonce from LM response.
447 * @ntlm_resp: ntlm response data from client.
448 *
449 * Return: 0 on success, error number on error
450 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900451static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce,
452 char *ntlm_resp)
Namjae Jeone2f34482021-03-16 10:49:09 +0900453{
454 char sess_key[CIFS_SMB1_SESSKEY_SIZE] = {0};
455 int rc;
456 unsigned char p21[21];
457 char key[CIFS_AUTH_RESP_SIZE];
458
459 rc = ksmbd_enc_update_sess_key(sess_key,
460 client_nonce,
461 (char *)sess->ntlmssp.cryptkey, 8);
462 if (rc) {
463 ksmbd_err("password processing failed\n");
464 goto out;
465 }
466
467 memset(p21, '\0', 21);
468 memcpy(p21, user_passkey(sess->user), CIFS_NTHASH_SIZE);
469 rc = ksmbd_enc_p24(p21, sess_key, key);
470 if (rc) {
471 ksmbd_err("password processing failed\n");
472 goto out;
473 }
474
Namjae Jeonb72802a2021-05-26 15:29:24 +0900475 if (memcmp(ntlm_resp, key, CIFS_AUTH_RESP_SIZE) != 0)
476 rc = -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +0900477out:
478 return rc;
479}
480
481/**
482 * ksmbd_decode_ntlmssp_auth_blob() - helper function to construct
483 * authenticate blob
484 * @authblob: authenticate blob source pointer
485 * @usr: user details
486 * @sess: session of connection
487 *
488 * Return: 0 on success, error number on error
489 */
490int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
Namjae Jeon64b39f42021-03-30 14:25:35 +0900491 int blob_len, struct ksmbd_session *sess)
Namjae Jeone2f34482021-03-16 10:49:09 +0900492{
493 char *domain_name;
494 unsigned int lm_off, nt_off;
495 unsigned short nt_len;
496 int ret;
497
498 if (blob_len < sizeof(struct authenticate_message)) {
499 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
500 blob_len);
501 return -EINVAL;
502 }
503
504 if (memcmp(authblob->Signature, "NTLMSSP", 8)) {
505 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
506 authblob->Signature);
507 return -EINVAL;
508 }
509
510 lm_off = le32_to_cpu(authblob->LmChallengeResponse.BufferOffset);
511 nt_off = le32_to_cpu(authblob->NtChallengeResponse.BufferOffset);
512 nt_len = le16_to_cpu(authblob->NtChallengeResponse.Length);
513
514 /* process NTLM authentication */
515 if (nt_len == CIFS_AUTH_RESP_SIZE) {
Namjae Jeon64b39f42021-03-30 14:25:35 +0900516 if (le32_to_cpu(authblob->NegotiateFlags) &
517 NTLMSSP_NEGOTIATE_EXTENDED_SEC)
Namjae Jeone2f34482021-03-16 10:49:09 +0900518 return __ksmbd_auth_ntlmv2(sess, (char *)authblob +
519 lm_off, (char *)authblob + nt_off);
520 else
521 return ksmbd_auth_ntlm(sess, (char *)authblob +
522 nt_off);
523 }
524
525 /* TODO : use domain name that imported from configuration file */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900526 domain_name = smb_strndup_from_utf16((const char *)authblob +
Namjae Jeone2f34482021-03-16 10:49:09 +0900527 le32_to_cpu(authblob->DomainName.BufferOffset),
528 le16_to_cpu(authblob->DomainName.Length), true,
529 sess->conn->local_nls);
530 if (IS_ERR(domain_name))
531 return PTR_ERR(domain_name);
532
533 /* process NTLMv2 authentication */
534 ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
535 domain_name);
536 ret = ksmbd_auth_ntlmv2(sess,
537 (struct ntlmv2_resp *)((char *)authblob + nt_off),
538 nt_len - CIFS_ENCPWD_SIZE,
539 domain_name);
540 kfree(domain_name);
541 return ret;
542}
543
544/**
545 * ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
546 * negotiate blob
547 * @negblob: negotiate blob source pointer
548 * @rsp: response header pointer to be updated
549 * @sess: session of connection
550 *
551 */
552int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
Namjae Jeon64b39f42021-03-30 14:25:35 +0900553 int blob_len, struct ksmbd_session *sess)
Namjae Jeone2f34482021-03-16 10:49:09 +0900554{
555 if (blob_len < sizeof(struct negotiate_message)) {
556 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
557 blob_len);
558 return -EINVAL;
559 }
560
561 if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
562 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
563 negblob->Signature);
564 return -EINVAL;
565 }
566
567 sess->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
568 return 0;
569}
570
571/**
572 * ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
573 * challenge blob
574 * @chgblob: challenge blob source pointer to initialize
575 * @rsp: response header pointer to be updated
576 * @sess: session of connection
577 *
578 */
579unsigned int
580ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
581 struct ksmbd_session *sess)
582{
583 struct target_info *tinfo;
584 wchar_t *name;
585 __u8 *target_name;
586 unsigned int len, flags, blob_off, blob_len, type, target_info_len = 0;
587 int cflags = sess->ntlmssp.client_flags;
588
589 memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
590 chgblob->MessageType = NtLmChallenge;
591
592 flags = NTLMSSP_NEGOTIATE_UNICODE |
593 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
594 NTLMSSP_NEGOTIATE_TARGET_INFO;
595
596 if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
597 flags |= NTLMSSP_NEGOTIATE_SIGN;
598 flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
Namjae Jeon70478052021-05-26 16:36:15 +0900599 NTLMSSP_NEGOTIATE_56);
Namjae Jeone2f34482021-03-16 10:49:09 +0900600 }
601
602 if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
603 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
604
605 if (cflags & NTLMSSP_REQUEST_TARGET)
606 flags |= NTLMSSP_REQUEST_TARGET;
607
608 if (sess->conn->use_spnego &&
Namjae Jeon64b39f42021-03-30 14:25:35 +0900609 (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
Namjae Jeone2f34482021-03-16 10:49:09 +0900610 flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
611
612 chgblob->NegotiateFlags = cpu_to_le32(flags);
613 len = strlen(ksmbd_netbios_name());
614 name = kmalloc(2 + (len * 2), GFP_KERNEL);
615 if (!name)
616 return -ENOMEM;
617
618 len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
619 sess->conn->local_nls);
620 len = UNICODE_LEN(len);
621
622 blob_off = sizeof(struct challenge_message);
623 blob_len = blob_off + len;
624
625 chgblob->TargetName.Length = cpu_to_le16(len);
626 chgblob->TargetName.MaximumLength = cpu_to_le16(len);
627 chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
628
629 /* Initialize random conn challenge */
630 get_random_bytes(sess->ntlmssp.cryptkey, sizeof(__u64));
631 memcpy(chgblob->Challenge, sess->ntlmssp.cryptkey,
632 CIFS_CRYPTO_KEY_SIZE);
633
634 /* Add Target Information to security buffer */
635 chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
636
637 target_name = (__u8 *)chgblob + blob_off;
638 memcpy(target_name, name, len);
639 tinfo = (struct target_info *)(target_name + len);
640
641 chgblob->TargetInfoArray.Length = 0;
642 /* Add target info list for NetBIOS/DNS settings */
643 for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
Namjae Jeon70478052021-05-26 16:36:15 +0900644 type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
Namjae Jeone2f34482021-03-16 10:49:09 +0900645 tinfo->Type = cpu_to_le16(type);
646 tinfo->Length = cpu_to_le16(len);
647 memcpy(tinfo->Content, name, len);
648 tinfo = (struct target_info *)((char *)tinfo + 4 + len);
649 target_info_len += 4 + len;
650 }
651
652 /* Add terminator subblock */
653 tinfo->Type = 0;
654 tinfo->Length = 0;
655 target_info_len += 4;
656
657 chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
658 chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
659 blob_len += target_info_len;
660 kfree(name);
661 ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
662 return blob_len;
663}
664
665#ifdef CONFIG_SMB_SERVER_KERBEROS5
Namjae Jeon64b39f42021-03-30 14:25:35 +0900666int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
667 int in_len, char *out_blob, int *out_len)
Namjae Jeone2f34482021-03-16 10:49:09 +0900668{
669 struct ksmbd_spnego_authen_response *resp;
670 struct ksmbd_user *user = NULL;
671 int retval;
672
673 resp = ksmbd_ipc_spnego_authen_request(in_blob, in_len);
674 if (!resp) {
675 ksmbd_debug(AUTH, "SPNEGO_AUTHEN_REQUEST failure\n");
676 return -EINVAL;
677 }
678
679 if (!(resp->login_response.status & KSMBD_USER_FLAG_OK)) {
680 ksmbd_debug(AUTH, "krb5 authentication failure\n");
681 retval = -EPERM;
682 goto out;
683 }
684
685 if (*out_len <= resp->spnego_blob_len) {
686 ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
687 *out_len, resp->spnego_blob_len);
688 retval = -EINVAL;
689 goto out;
690 }
691
692 if (resp->session_key_len > sizeof(sess->sess_key)) {
693 ksmbd_debug(AUTH, "session key is too long\n");
694 retval = -EINVAL;
695 goto out;
696 }
697
698 user = ksmbd_alloc_user(&resp->login_response);
699 if (!user) {
700 ksmbd_debug(AUTH, "login failure\n");
701 retval = -ENOMEM;
702 goto out;
703 }
704 sess->user = user;
705
706 memcpy(sess->sess_key, resp->payload, resp->session_key_len);
707 memcpy(out_blob, resp->payload + resp->session_key_len,
708 resp->spnego_blob_len);
709 *out_len = resp->spnego_blob_len;
710 retval = 0;
711out:
Namjae Jeon79f6b112021-04-02 12:47:14 +0900712 kvfree(resp);
Namjae Jeone2f34482021-03-16 10:49:09 +0900713 return retval;
714}
715#else
Namjae Jeon64b39f42021-03-30 14:25:35 +0900716int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
717 int in_len, char *out_blob, int *out_len)
Namjae Jeone2f34482021-03-16 10:49:09 +0900718{
719 return -EOPNOTSUPP;
720}
721#endif
722
723/**
724 * ksmbd_sign_smb2_pdu() - function to generate packet signing
725 * @conn: connection
726 * @key: signing key
727 * @iov: buffer iov array
728 * @n_vec: number of iovecs
729 * @sig: signature value generated for client request packet
730 *
731 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900732int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
733 int n_vec, char *sig)
Namjae Jeone2f34482021-03-16 10:49:09 +0900734{
735 struct ksmbd_crypto_ctx *ctx;
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900736 int rc, i;
Namjae Jeone2f34482021-03-16 10:49:09 +0900737
738 ctx = ksmbd_crypto_ctx_find_hmacsha256();
739 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900740 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
741 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900742 }
743
744 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
745 key,
746 SMB2_NTLMV2_SESSKEY_SIZE);
747 if (rc)
748 goto out;
749
750 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
751 if (rc) {
752 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
753 goto out;
754 }
755
756 for (i = 0; i < n_vec; i++) {
757 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
758 iov[i].iov_base,
759 iov[i].iov_len);
760 if (rc) {
761 ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
762 goto out;
763 }
764 }
765
766 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
767 if (rc)
768 ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
769out:
770 ksmbd_release_crypto_ctx(ctx);
771 return rc;
772}
773
774/**
775 * ksmbd_sign_smb3_pdu() - function to generate packet signing
776 * @conn: connection
777 * @key: signing key
778 * @iov: buffer iov array
779 * @n_vec: number of iovecs
780 * @sig: signature value generated for client request packet
781 *
782 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900783int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
784 int n_vec, char *sig)
Namjae Jeone2f34482021-03-16 10:49:09 +0900785{
786 struct ksmbd_crypto_ctx *ctx;
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900787 int rc, i;
Namjae Jeone2f34482021-03-16 10:49:09 +0900788
789 ctx = ksmbd_crypto_ctx_find_cmacaes();
790 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900791 ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
792 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900793 }
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 Jeon0e579cd2021-05-26 16:34:56 +0900838 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +0900839 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) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900848 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
849 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900850 }
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{
Namjae Jeon0e579cd2021-05-26 16:34:56 +09001060 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +09001061 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
Namjae Jeond3cd8c42021-05-26 15:56:18 +09001066 if (conn->preauth_info->Preauth_HashId !=
1067 SMB2_PREAUTH_INTEGRITY_SHA512)
1068 return -EINVAL;
1069
1070 ctx = ksmbd_crypto_ctx_find_sha512();
1071 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +09001072 ksmbd_debug(AUTH, "could not alloc sha512\n");
1073 return -ENOMEM;
Namjae Jeon64b39f42021-03-30 14:25:35 +09001074 }
Namjae Jeone2f34482021-03-16 10:49:09 +09001075
1076 rc = crypto_shash_init(CRYPTO_SHA512(ctx));
1077 if (rc) {
1078 ksmbd_debug(AUTH, "could not init shashn");
1079 goto out;
1080 }
1081
1082 rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
1083 if (rc) {
1084 ksmbd_debug(AUTH, "could not update with n\n");
1085 goto out;
1086 }
1087
1088 rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
1089 if (rc) {
1090 ksmbd_debug(AUTH, "could not update with n\n");
1091 goto out;
1092 }
1093
1094 rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
1095 if (rc) {
1096 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
1097 goto out;
1098 }
1099out:
1100 ksmbd_release_crypto_ctx(ctx);
1101 return rc;
1102}
1103
1104int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
1105 __u8 *pi_hash)
1106{
Namjae Jeon0e579cd2021-05-26 16:34:56 +09001107 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +09001108 struct ksmbd_crypto_ctx *ctx = NULL;
1109
1110 ctx = ksmbd_crypto_ctx_find_sha256();
1111 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +09001112 ksmbd_debug(AUTH, "could not alloc sha256\n");
1113 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +09001114 }
1115
1116 rc = crypto_shash_init(CRYPTO_SHA256(ctx));
1117 if (rc) {
1118 ksmbd_debug(AUTH, "could not init shashn");
1119 goto out;
1120 }
1121
1122 rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
1123 if (rc) {
1124 ksmbd_debug(AUTH, "could not update with n\n");
1125 goto out;
1126 }
1127
1128 rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
1129 if (rc) {
1130 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
1131 goto out;
1132 }
1133out:
1134 ksmbd_release_crypto_ctx(ctx);
1135 return rc;
1136}
1137
Namjae Jeon64b39f42021-03-30 14:25:35 +09001138static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
1139 int enc, u8 *key)
Namjae Jeone2f34482021-03-16 10:49:09 +09001140{
1141 struct ksmbd_session *sess;
1142 u8 *ses_enc_key;
1143
1144 sess = ksmbd_session_lookup(conn, ses_id);
1145 if (!sess)
Namjae Jeon522dcc72021-05-26 15:30:50 +09001146 return -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +09001147
1148 ses_enc_key = enc ? sess->smb3encryptionkey :
1149 sess->smb3decryptionkey;
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001150 memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +09001151
1152 return 0;
1153}
1154
1155static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
1156 unsigned int buflen)
1157{
1158 void *addr;
1159
1160 if (is_vmalloc_addr(buf))
1161 addr = vmalloc_to_page(buf);
1162 else
1163 addr = virt_to_page(buf);
1164 sg_set_page(sg, addr, buflen, offset_in_page(buf));
1165}
1166
Namjae Jeon64b39f42021-03-30 14:25:35 +09001167static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
1168 u8 *sign)
Namjae Jeone2f34482021-03-16 10:49:09 +09001169{
1170 struct scatterlist *sg;
1171 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
1172 int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0;
1173
Namjae Jeon41a78482021-05-26 15:31:37 +09001174 if (!nvec)
1175 return NULL;
1176
Namjae Jeone2f34482021-03-16 10:49:09 +09001177 for (i = 0; i < nvec - 1; i++) {
1178 unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
1179
1180 if (is_vmalloc_addr(iov[i + 1].iov_base)) {
1181 nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
1182 PAGE_SIZE - 1) >> PAGE_SHIFT) -
1183 (kaddr >> PAGE_SHIFT);
Namjae Jeon64b39f42021-03-30 14:25:35 +09001184 } else {
Namjae Jeone2f34482021-03-16 10:49:09 +09001185 nr_entries[i]++;
Namjae Jeon64b39f42021-03-30 14:25:35 +09001186 }
Namjae Jeone2f34482021-03-16 10:49:09 +09001187 total_entries += nr_entries[i];
1188 }
1189
1190 /* Add two entries for transform header and signature */
1191 total_entries += 2;
1192
1193 sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
1194 if (!sg)
1195 return NULL;
1196
1197 sg_init_table(sg, total_entries);
1198 smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1199 for (i = 0; i < nvec - 1; i++) {
1200 void *data = iov[i + 1].iov_base;
1201 int len = iov[i + 1].iov_len;
1202
1203 if (is_vmalloc_addr(data)) {
1204 int j, offset = offset_in_page(data);
1205
1206 for (j = 0; j < nr_entries[i]; j++) {
1207 unsigned int bytes = PAGE_SIZE - offset;
1208
Namjae Jeon08591cc2021-05-26 15:32:26 +09001209 if (!len)
Namjae Jeone2f34482021-03-16 10:49:09 +09001210 break;
1211
1212 if (bytes > len)
1213 bytes = len;
1214
1215 sg_set_page(&sg[sg_idx++],
1216 vmalloc_to_page(data), bytes,
1217 offset_in_page(data));
1218
1219 data += bytes;
1220 len -= bytes;
1221 offset = 0;
1222 }
1223 } else {
1224 sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1225 offset_in_page(data));
1226 }
Namjae Jeone2f34482021-03-16 10:49:09 +09001227 }
1228 smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1229 return sg;
1230}
1231
Namjae Jeon64b39f42021-03-30 14:25:35 +09001232int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
1233 unsigned int nvec, int enc)
Namjae Jeone2f34482021-03-16 10:49:09 +09001234{
1235 struct smb2_transform_hdr *tr_hdr =
1236 (struct smb2_transform_hdr *)iov[0].iov_base;
1237 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
Namjae Jeon03f1c3d2021-05-26 15:34:37 +09001238 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +09001239 struct scatterlist *sg;
1240 u8 sign[SMB2_SIGNATURE_SIZE] = {};
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001241 u8 key[SMB3_ENC_DEC_KEY_SIZE];
Namjae Jeone2f34482021-03-16 10:49:09 +09001242 struct aead_request *req;
1243 char *iv;
1244 unsigned int iv_len;
1245 struct crypto_aead *tfm;
1246 unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1247 struct ksmbd_crypto_ctx *ctx;
1248
1249 rc = ksmbd_get_encryption_key(conn,
1250 le64_to_cpu(tr_hdr->SessionId),
1251 enc,
1252 key);
1253 if (rc) {
1254 ksmbd_err("Could not get %scryption key\n", enc ? "en" : "de");
Namjae Jeon27aa6462021-05-26 15:35:26 +09001255 return rc;
Namjae Jeone2f34482021-03-16 10:49:09 +09001256 }
1257
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001258 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1259 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
Namjae Jeone2f34482021-03-16 10:49:09 +09001260 ctx = ksmbd_crypto_ctx_find_gcm();
1261 else
1262 ctx = ksmbd_crypto_ctx_find_ccm();
1263 if (!ctx) {
1264 ksmbd_err("crypto alloc failed\n");
Namjae Jeon0e579cd2021-05-26 16:34:56 +09001265 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +09001266 }
1267
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001268 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1269 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
Namjae Jeone2f34482021-03-16 10:49:09 +09001270 tfm = CRYPTO_GCM(ctx);
1271 else
1272 tfm = CRYPTO_CCM(ctx);
1273
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001274 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1275 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1276 rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1277 else
1278 rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +09001279 if (rc) {
1280 ksmbd_err("Failed to set aead key %d\n", rc);
1281 goto free_ctx;
1282 }
1283
1284 rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1285 if (rc) {
1286 ksmbd_err("Failed to set authsize %d\n", rc);
1287 goto free_ctx;
1288 }
1289
1290 req = aead_request_alloc(tfm, GFP_KERNEL);
1291 if (!req) {
1292 ksmbd_err("Failed to alloc aead request\n");
1293 rc = -ENOMEM;
1294 goto free_ctx;
1295 }
1296
1297 if (!enc) {
1298 memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1299 crypt_len += SMB2_SIGNATURE_SIZE;
1300 }
1301
1302 sg = ksmbd_init_sg(iov, nvec, sign);
1303 if (!sg) {
1304 ksmbd_err("Failed to init sg\n");
1305 rc = -ENOMEM;
1306 goto free_req;
1307 }
1308
1309 iv_len = crypto_aead_ivsize(tfm);
1310 iv = kzalloc(iv_len, GFP_KERNEL);
1311 if (!iv) {
1312 ksmbd_err("Failed to alloc IV\n");
1313 rc = -ENOMEM;
1314 goto free_sg;
1315 }
1316
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001317 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1318 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1319 memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
Namjae Jeon64b39f42021-03-30 14:25:35 +09001320 } else {
Namjae Jeone2f34482021-03-16 10:49:09 +09001321 iv[0] = 3;
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001322 memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
Namjae Jeone2f34482021-03-16 10:49:09 +09001323 }
1324
1325 aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1326 aead_request_set_ad(req, assoc_data_len);
1327 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1328
1329 if (enc)
1330 rc = crypto_aead_encrypt(req);
1331 else
1332 rc = crypto_aead_decrypt(req);
Namjae Jeon73b8b082021-05-26 15:53:26 +09001333 if (rc)
1334 goto free_iv;
1335
1336 if (enc)
Namjae Jeone2f34482021-03-16 10:49:09 +09001337 memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1338
Namjae Jeon73b8b082021-05-26 15:53:26 +09001339free_iv:
Namjae Jeone2f34482021-03-16 10:49:09 +09001340 kfree(iv);
1341free_sg:
1342 kfree(sg);
1343free_req:
1344 kfree(req);
1345free_ctx:
1346 ksmbd_release_crypto_ctx(ctx);
1347 return rc;
1348}