blob: 911444d212673bf5ae2d639ab246577e1cd33a63 [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"
Namjae Jeonf9929ef2022-02-01 18:20:34 +090032#include "../smbfs_common/arc4.h"
Namjae Jeone2f34482021-03-16 10:49:09 +090033
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
Namjae Jeone2f34482021-03-16 10:49:09 +090072/**
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 */
Namjae Jeon64b39f42021-03-30 14:25:35 +090079static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
Namjae Jeon070fb212021-05-26 17:57:12 +090080 char *hmac)
Namjae Jeone2f34482021-03-16 10:49:09 +090081{
82 struct ksmbd_crypto_ctx *ctx;
Namjae Jeon0e579cd2021-05-26 16:34:56 +090083 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +090084
85 ctx = ksmbd_crypto_ctx_find_hmacmd5();
Namjae Jeon0e579cd2021-05-26 16:34:56 +090086 if (!ctx) {
87 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
88 return -ENOMEM;
89 }
Namjae Jeone2f34482021-03-16 10:49:09 +090090
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) {
Namjae Jeon070fb212021-05-26 17:57:12 +0900109 ksmbd_debug(AUTH, "Could not update with response error %d\n", rc);
Namjae Jeone2f34482021-03-16 10:49:09 +0900110 goto out;
111 }
112
113 rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
114 if (rc) {
Namjae Jeon070fb212021-05-26 17:57:12 +0900115 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n", rc);
Namjae Jeone2f34482021-03-16 10:49:09 +0900116 goto out;
117 }
118
119out:
120 ksmbd_release_crypto_ctx(ctx);
121 return rc;
122}
123
124static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
Namjae Jeon070fb212021-05-26 17:57:12 +0900125 char *dname)
Namjae Jeone2f34482021-03-16 10:49:09 +0900126{
Namjae Jeona2d0b502021-05-26 16:37:05 +0900127 int ret, len, conv_len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900128 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");
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900135 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900136 }
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
Namjae Jeona2d0b502021-05-26 16:37:05 +0900160 conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
Namjae Jeon070fb212021-05-26 17:57:12 +0900161 sess->conn->local_nls);
Namjae Jeona2d0b502021-05-26 16:37:05 +0900162 if (conv_len < 0 || conv_len > len) {
163 ret = -EINVAL;
164 goto out;
Namjae Jeone2f34482021-03-16 10:49:09 +0900165 }
Namjae Jeona2d0b502021-05-26 16:37:05 +0900166 UniStrupr(uniname);
Namjae Jeone2f34482021-03-16 10:49:09 +0900167
168 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
169 (char *)uniname,
Namjae Jeona2d0b502021-05-26 16:37:05 +0900170 UNICODE_LEN(conv_len));
Namjae Jeone2f34482021-03-16 10:49:09 +0900171 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
Namjae Jeona2d0b502021-05-26 16:37:05 +0900184 conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
Namjae Jeon070fb212021-05-26 17:57:12 +0900185 sess->conn->local_nls);
Namjae Jeona2d0b502021-05-26 16:37:05 +0900186 if (conv_len < 0 || conv_len > len) {
187 ret = -EINVAL;
188 goto out;
189 }
Namjae Jeone2f34482021-03-16 10:49:09 +0900190
191 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
192 (char *)domain,
Namjae Jeona2d0b502021-05-26 16:37:05 +0900193 UNICODE_LEN(conv_len));
Namjae Jeone2f34482021-03-16 10:49:09 +0900194 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);
Namjae Jeone2f34482021-03-16 10:49:09 +0900200 if (ret)
201 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
Namjae Jeon7e38ea22021-05-26 15:27:11 +0900202out:
Namjae Jeone2f34482021-03-16 10:49:09 +0900203 kfree(uniname);
204 kfree(domain);
205 ksmbd_release_crypto_ctx(ctx);
206 return ret;
207}
208
209/**
Namjae Jeone2f34482021-03-16 10:49:09 +0900210 * 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 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900218int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
Namjae Jeonce53d362021-12-15 14:57:27 +0900219 int blen, char *domain_name, char *cryptkey)
Namjae Jeone2f34482021-03-16 10:49:09 +0900220{
221 char ntlmv2_hash[CIFS_ENCPWD_SIZE];
222 char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
223 struct ksmbd_crypto_ctx *ctx;
224 char *construct = NULL;
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900225 int rc, len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900226
227 ctx = ksmbd_crypto_ctx_find_hmacmd5();
228 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900229 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
230 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900231 }
232
233 rc = calc_ntlmv2_hash(sess, ntlmv2_hash, domain_name);
234 if (rc) {
235 ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
236 goto out;
237 }
238
239 rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
240 ntlmv2_hash,
241 CIFS_HMAC_MD5_HASH_SIZE);
242 if (rc) {
243 ksmbd_debug(AUTH, "Could not set NTLMV2 Hash as a key\n");
244 goto out;
245 }
246
247 rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
248 if (rc) {
249 ksmbd_debug(AUTH, "Could not init hmacmd5\n");
250 goto out;
251 }
252
253 len = CIFS_CRYPTO_KEY_SIZE + blen;
254 construct = kzalloc(len, GFP_KERNEL);
255 if (!construct) {
256 rc = -ENOMEM;
257 goto out;
258 }
259
Namjae Jeonce53d362021-12-15 14:57:27 +0900260 memcpy(construct, cryptkey, CIFS_CRYPTO_KEY_SIZE);
Namjae Jeon192cc732021-05-26 15:28:48 +0900261 memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
Namjae Jeone2f34482021-03-16 10:49:09 +0900262
263 rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
264 if (rc) {
265 ksmbd_debug(AUTH, "Could not update with response\n");
266 goto out;
267 }
268
269 rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_rsp);
270 if (rc) {
271 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
272 goto out;
273 }
274
275 rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
276 if (rc) {
277 ksmbd_debug(AUTH, "Could not generate sess key\n");
278 goto out;
279 }
280
Namjae Jeonb72802a2021-05-26 15:29:24 +0900281 if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
282 rc = -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +0900283out:
284 ksmbd_release_crypto_ctx(ctx);
285 kfree(construct);
286 return rc;
287}
288
289/**
Namjae Jeone2f34482021-03-16 10:49:09 +0900290 * ksmbd_decode_ntlmssp_auth_blob() - helper function to construct
291 * authenticate blob
292 * @authblob: authenticate blob source pointer
293 * @usr: user details
294 * @sess: session of connection
295 *
296 * Return: 0 on success, error number on error
297 */
298int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
Namjae Jeonce53d362021-12-15 14:57:27 +0900299 int blob_len, struct ksmbd_conn *conn,
300 struct ksmbd_session *sess)
Namjae Jeone2f34482021-03-16 10:49:09 +0900301{
302 char *domain_name;
Marios Makassikis0d994cd2021-10-19 17:39:38 +0200303 unsigned int nt_off, dn_off;
304 unsigned short nt_len, dn_len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900305 int ret;
306
307 if (blob_len < sizeof(struct authenticate_message)) {
308 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900309 blob_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900310 return -EINVAL;
311 }
312
313 if (memcmp(authblob->Signature, "NTLMSSP", 8)) {
314 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900315 authblob->Signature);
Namjae Jeone2f34482021-03-16 10:49:09 +0900316 return -EINVAL;
317 }
318
Namjae Jeone2f34482021-03-16 10:49:09 +0900319 nt_off = le32_to_cpu(authblob->NtChallengeResponse.BufferOffset);
320 nt_len = le16_to_cpu(authblob->NtChallengeResponse.Length);
Marios Makassikis0d994cd2021-10-19 17:39:38 +0200321 dn_off = le32_to_cpu(authblob->DomainName.BufferOffset);
322 dn_len = le16_to_cpu(authblob->DomainName.Length);
323
324 if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len)
325 return -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +0900326
Namjae Jeone2f34482021-03-16 10:49:09 +0900327 /* TODO : use domain name that imported from configuration file */
Marios Makassikis0d994cd2021-10-19 17:39:38 +0200328 domain_name = smb_strndup_from_utf16((const char *)authblob + dn_off,
Namjae Jeonce53d362021-12-15 14:57:27 +0900329 dn_len, true, conn->local_nls);
Namjae Jeone2f34482021-03-16 10:49:09 +0900330 if (IS_ERR(domain_name))
331 return PTR_ERR(domain_name);
332
333 /* process NTLMv2 authentication */
334 ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900335 domain_name);
336 ret = ksmbd_auth_ntlmv2(sess, (struct ntlmv2_resp *)((char *)authblob + nt_off),
337 nt_len - CIFS_ENCPWD_SIZE,
Namjae Jeonce53d362021-12-15 14:57:27 +0900338 domain_name, conn->ntlmssp.cryptkey);
Namjae Jeone2f34482021-03-16 10:49:09 +0900339 kfree(domain_name);
Namjae Jeonf9929ef2022-02-01 18:20:34 +0900340
341 /* The recovered secondary session key */
342 if (conn->ntlmssp.client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) {
343 struct arc4_ctx *ctx_arc4;
344 unsigned int sess_key_off, sess_key_len;
345
346 sess_key_off = le32_to_cpu(authblob->SessionKey.BufferOffset);
347 sess_key_len = le16_to_cpu(authblob->SessionKey.Length);
348
349 if (blob_len < (u64)sess_key_off + sess_key_len)
350 return -EINVAL;
351
352 ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL);
353 if (!ctx_arc4)
354 return -ENOMEM;
355
356 cifs_arc4_setkey(ctx_arc4, sess->sess_key,
357 SMB2_NTLMV2_SESSKEY_SIZE);
358 cifs_arc4_crypt(ctx_arc4, sess->sess_key,
359 (char *)authblob + sess_key_off, sess_key_len);
360 kfree_sensitive(ctx_arc4);
361 }
362
Namjae Jeone2f34482021-03-16 10:49:09 +0900363 return ret;
364}
365
366/**
367 * ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
368 * negotiate blob
369 * @negblob: negotiate blob source pointer
370 * @rsp: response header pointer to be updated
371 * @sess: session of connection
372 *
373 */
374int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
Namjae Jeonce53d362021-12-15 14:57:27 +0900375 int blob_len, struct ksmbd_conn *conn)
Namjae Jeone2f34482021-03-16 10:49:09 +0900376{
377 if (blob_len < sizeof(struct negotiate_message)) {
378 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900379 blob_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900380 return -EINVAL;
381 }
382
383 if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
384 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900385 negblob->Signature);
Namjae Jeone2f34482021-03-16 10:49:09 +0900386 return -EINVAL;
387 }
388
Namjae Jeonce53d362021-12-15 14:57:27 +0900389 conn->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
Namjae Jeone2f34482021-03-16 10:49:09 +0900390 return 0;
391}
392
393/**
394 * ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
395 * challenge blob
396 * @chgblob: challenge blob source pointer to initialize
397 * @rsp: response header pointer to be updated
398 * @sess: session of connection
399 *
400 */
401unsigned int
402ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
Namjae Jeonce53d362021-12-15 14:57:27 +0900403 struct ksmbd_conn *conn)
Namjae Jeone2f34482021-03-16 10:49:09 +0900404{
405 struct target_info *tinfo;
406 wchar_t *name;
407 __u8 *target_name;
Namjae Jeon152de8c2021-05-29 07:59:40 +0900408 unsigned int flags, blob_off, blob_len, type, target_info_len = 0;
409 int len, uni_len, conv_len;
Namjae Jeonce53d362021-12-15 14:57:27 +0900410 int cflags = conn->ntlmssp.client_flags;
Namjae Jeone2f34482021-03-16 10:49:09 +0900411
412 memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
413 chgblob->MessageType = NtLmChallenge;
414
415 flags = NTLMSSP_NEGOTIATE_UNICODE |
416 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
417 NTLMSSP_NEGOTIATE_TARGET_INFO;
418
419 if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
420 flags |= NTLMSSP_NEGOTIATE_SIGN;
421 flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
Namjae Jeon70478052021-05-26 16:36:15 +0900422 NTLMSSP_NEGOTIATE_56);
Namjae Jeone2f34482021-03-16 10:49:09 +0900423 }
424
425 if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
426 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
427
428 if (cflags & NTLMSSP_REQUEST_TARGET)
429 flags |= NTLMSSP_REQUEST_TARGET;
430
Namjae Jeonce53d362021-12-15 14:57:27 +0900431 if (conn->use_spnego &&
Namjae Jeon64b39f42021-03-30 14:25:35 +0900432 (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
Namjae Jeone2f34482021-03-16 10:49:09 +0900433 flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
434
Namjae Jeonf9929ef2022-02-01 18:20:34 +0900435 if (cflags & NTLMSSP_NEGOTIATE_KEY_XCH)
436 flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
437
Namjae Jeone2f34482021-03-16 10:49:09 +0900438 chgblob->NegotiateFlags = cpu_to_le32(flags);
439 len = strlen(ksmbd_netbios_name());
Namjae Jeona2d0b502021-05-26 16:37:05 +0900440 name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
Namjae Jeone2f34482021-03-16 10:49:09 +0900441 if (!name)
442 return -ENOMEM;
443
Namjae Jeona2d0b502021-05-26 16:37:05 +0900444 conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
Namjae Jeonce53d362021-12-15 14:57:27 +0900445 conn->local_nls);
Namjae Jeona2d0b502021-05-26 16:37:05 +0900446 if (conv_len < 0 || conv_len > len) {
447 kfree(name);
448 return -EINVAL;
449 }
450
451 uni_len = UNICODE_LEN(conv_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900452
453 blob_off = sizeof(struct challenge_message);
Namjae Jeona2d0b502021-05-26 16:37:05 +0900454 blob_len = blob_off + uni_len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900455
Namjae Jeona2d0b502021-05-26 16:37:05 +0900456 chgblob->TargetName.Length = cpu_to_le16(uni_len);
457 chgblob->TargetName.MaximumLength = cpu_to_le16(uni_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900458 chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
459
460 /* Initialize random conn challenge */
Namjae Jeonce53d362021-12-15 14:57:27 +0900461 get_random_bytes(conn->ntlmssp.cryptkey, sizeof(__u64));
462 memcpy(chgblob->Challenge, conn->ntlmssp.cryptkey,
Namjae Jeon070fb212021-05-26 17:57:12 +0900463 CIFS_CRYPTO_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900464
465 /* Add Target Information to security buffer */
466 chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
467
468 target_name = (__u8 *)chgblob + blob_off;
Namjae Jeona2d0b502021-05-26 16:37:05 +0900469 memcpy(target_name, name, uni_len);
470 tinfo = (struct target_info *)(target_name + uni_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900471
472 chgblob->TargetInfoArray.Length = 0;
473 /* Add target info list for NetBIOS/DNS settings */
474 for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
Namjae Jeon70478052021-05-26 16:36:15 +0900475 type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
Namjae Jeone2f34482021-03-16 10:49:09 +0900476 tinfo->Type = cpu_to_le16(type);
Namjae Jeona2d0b502021-05-26 16:37:05 +0900477 tinfo->Length = cpu_to_le16(uni_len);
478 memcpy(tinfo->Content, name, uni_len);
479 tinfo = (struct target_info *)((char *)tinfo + 4 + uni_len);
480 target_info_len += 4 + uni_len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900481 }
482
483 /* Add terminator subblock */
484 tinfo->Type = 0;
485 tinfo->Length = 0;
486 target_info_len += 4;
487
488 chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
489 chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
490 blob_len += target_info_len;
491 kfree(name);
492 ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
493 return blob_len;
494}
495
496#ifdef CONFIG_SMB_SERVER_KERBEROS5
Namjae Jeon64b39f42021-03-30 14:25:35 +0900497int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
Namjae Jeon070fb212021-05-26 17:57:12 +0900498 int in_len, char *out_blob, int *out_len)
Namjae Jeone2f34482021-03-16 10:49:09 +0900499{
500 struct ksmbd_spnego_authen_response *resp;
501 struct ksmbd_user *user = NULL;
502 int retval;
503
504 resp = ksmbd_ipc_spnego_authen_request(in_blob, in_len);
505 if (!resp) {
506 ksmbd_debug(AUTH, "SPNEGO_AUTHEN_REQUEST failure\n");
507 return -EINVAL;
508 }
509
510 if (!(resp->login_response.status & KSMBD_USER_FLAG_OK)) {
511 ksmbd_debug(AUTH, "krb5 authentication failure\n");
512 retval = -EPERM;
513 goto out;
514 }
515
516 if (*out_len <= resp->spnego_blob_len) {
517 ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900518 *out_len, resp->spnego_blob_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900519 retval = -EINVAL;
520 goto out;
521 }
522
523 if (resp->session_key_len > sizeof(sess->sess_key)) {
524 ksmbd_debug(AUTH, "session key is too long\n");
525 retval = -EINVAL;
526 goto out;
527 }
528
529 user = ksmbd_alloc_user(&resp->login_response);
530 if (!user) {
531 ksmbd_debug(AUTH, "login failure\n");
532 retval = -ENOMEM;
533 goto out;
534 }
535 sess->user = user;
536
537 memcpy(sess->sess_key, resp->payload, resp->session_key_len);
538 memcpy(out_blob, resp->payload + resp->session_key_len,
Namjae Jeon070fb212021-05-26 17:57:12 +0900539 resp->spnego_blob_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900540 *out_len = resp->spnego_blob_len;
541 retval = 0;
542out:
Namjae Jeon79f6b112021-04-02 12:47:14 +0900543 kvfree(resp);
Namjae Jeone2f34482021-03-16 10:49:09 +0900544 return retval;
545}
546#else
Namjae Jeon64b39f42021-03-30 14:25:35 +0900547int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
Namjae Jeon070fb212021-05-26 17:57:12 +0900548 int in_len, char *out_blob, int *out_len)
Namjae Jeone2f34482021-03-16 10:49:09 +0900549{
550 return -EOPNOTSUPP;
551}
552#endif
553
554/**
555 * ksmbd_sign_smb2_pdu() - function to generate packet signing
556 * @conn: connection
557 * @key: signing key
558 * @iov: buffer iov array
559 * @n_vec: number of iovecs
560 * @sig: signature value generated for client request packet
561 *
562 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900563int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
Namjae Jeon070fb212021-05-26 17:57:12 +0900564 int n_vec, char *sig)
Namjae Jeone2f34482021-03-16 10:49:09 +0900565{
566 struct ksmbd_crypto_ctx *ctx;
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900567 int rc, i;
Namjae Jeone2f34482021-03-16 10:49:09 +0900568
569 ctx = ksmbd_crypto_ctx_find_hmacsha256();
570 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900571 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
572 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900573 }
574
575 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
576 key,
577 SMB2_NTLMV2_SESSKEY_SIZE);
578 if (rc)
579 goto out;
580
581 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
582 if (rc) {
583 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
584 goto out;
585 }
586
587 for (i = 0; i < n_vec; i++) {
588 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
589 iov[i].iov_base,
590 iov[i].iov_len);
591 if (rc) {
592 ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
593 goto out;
594 }
595 }
596
597 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
598 if (rc)
599 ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
600out:
601 ksmbd_release_crypto_ctx(ctx);
602 return rc;
603}
604
605/**
606 * ksmbd_sign_smb3_pdu() - function to generate packet signing
607 * @conn: connection
608 * @key: signing key
609 * @iov: buffer iov array
610 * @n_vec: number of iovecs
611 * @sig: signature value generated for client request packet
612 *
613 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900614int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
Namjae Jeon070fb212021-05-26 17:57:12 +0900615 int n_vec, char *sig)
Namjae Jeone2f34482021-03-16 10:49:09 +0900616{
617 struct ksmbd_crypto_ctx *ctx;
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900618 int rc, i;
Namjae Jeone2f34482021-03-16 10:49:09 +0900619
620 ctx = ksmbd_crypto_ctx_find_cmacaes();
621 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900622 ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
623 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900624 }
625
626 rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
627 key,
628 SMB2_CMACAES_SIZE);
629 if (rc)
630 goto out;
631
632 rc = crypto_shash_init(CRYPTO_CMACAES(ctx));
633 if (rc) {
634 ksmbd_debug(AUTH, "cmaces init error %d\n", rc);
635 goto out;
636 }
637
638 for (i = 0; i < n_vec; i++) {
639 rc = crypto_shash_update(CRYPTO_CMACAES(ctx),
640 iov[i].iov_base,
641 iov[i].iov_len);
642 if (rc) {
643 ksmbd_debug(AUTH, "cmaces update error %d\n", rc);
644 goto out;
645 }
646 }
647
648 rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig);
649 if (rc)
650 ksmbd_debug(AUTH, "cmaces generation error %d\n", rc);
651out:
652 ksmbd_release_crypto_ctx(ctx);
653 return rc;
654}
655
656struct derivation {
657 struct kvec label;
658 struct kvec context;
659 bool binding;
660};
661
662static int generate_key(struct ksmbd_session *sess, struct kvec label,
Namjae Jeon070fb212021-05-26 17:57:12 +0900663 struct kvec context, __u8 *key, unsigned int key_size)
Namjae Jeone2f34482021-03-16 10:49:09 +0900664{
665 unsigned char zero = 0x0;
666 __u8 i[4] = {0, 0, 0, 1};
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900667 __u8 L128[4] = {0, 0, 0, 128};
668 __u8 L256[4] = {0, 0, 1, 0};
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900669 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +0900670 unsigned char prfhash[SMB2_HMACSHA256_SIZE];
671 unsigned char *hashptr = prfhash;
672 struct ksmbd_crypto_ctx *ctx;
673
674 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
675 memset(key, 0x0, key_size);
676
677 ctx = ksmbd_crypto_ctx_find_hmacsha256();
678 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900679 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
680 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900681 }
682
683 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
684 sess->sess_key,
685 SMB2_NTLMV2_SESSKEY_SIZE);
686 if (rc)
687 goto smb3signkey_ret;
688
689 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
690 if (rc) {
691 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
692 goto smb3signkey_ret;
693 }
694
695 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
696 if (rc) {
697 ksmbd_debug(AUTH, "could not update with n\n");
698 goto smb3signkey_ret;
699 }
700
701 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
702 label.iov_base,
703 label.iov_len);
704 if (rc) {
705 ksmbd_debug(AUTH, "could not update with label\n");
706 goto smb3signkey_ret;
707 }
708
709 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
710 if (rc) {
711 ksmbd_debug(AUTH, "could not update with zero\n");
712 goto smb3signkey_ret;
713 }
714
715 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
716 context.iov_base,
717 context.iov_len);
718 if (rc) {
719 ksmbd_debug(AUTH, "could not update with context\n");
720 goto smb3signkey_ret;
721 }
722
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900723 if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
724 sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
725 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
726 else
727 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
Namjae Jeone2f34482021-03-16 10:49:09 +0900728 if (rc) {
729 ksmbd_debug(AUTH, "could not update with L\n");
730 goto smb3signkey_ret;
731 }
732
733 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
734 if (rc) {
735 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900736 rc);
Namjae Jeone2f34482021-03-16 10:49:09 +0900737 goto smb3signkey_ret;
738 }
739
740 memcpy(key, hashptr, key_size);
741
742smb3signkey_ret:
743 ksmbd_release_crypto_ctx(ctx);
744 return rc;
745}
746
747static int generate_smb3signingkey(struct ksmbd_session *sess,
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900748 struct ksmbd_conn *conn,
Namjae Jeon070fb212021-05-26 17:57:12 +0900749 const struct derivation *signing)
Namjae Jeone2f34482021-03-16 10:49:09 +0900750{
751 int rc;
752 struct channel *chann;
753 char *key;
754
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900755 chann = lookup_chann_list(sess, conn);
Namjae Jeone2f34482021-03-16 10:49:09 +0900756 if (!chann)
757 return 0;
758
759 if (sess->conn->dialect >= SMB30_PROT_ID && signing->binding)
760 key = chann->smb3signingkey;
761 else
762 key = sess->smb3signingkey;
763
764 rc = generate_key(sess, signing->label, signing->context, key,
Namjae Jeon070fb212021-05-26 17:57:12 +0900765 SMB3_SIGN_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900766 if (rc)
767 return rc;
768
769 if (!(sess->conn->dialect >= SMB30_PROT_ID && signing->binding))
770 memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
771
772 ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
773 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
774 ksmbd_debug(AUTH, "Session Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900775 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
Namjae Jeone2f34482021-03-16 10:49:09 +0900776 ksmbd_debug(AUTH, "Signing Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900777 SMB3_SIGN_KEY_SIZE, key);
Namjae Jeon876edcc2021-05-26 15:30:04 +0900778 return 0;
Namjae Jeone2f34482021-03-16 10:49:09 +0900779}
780
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900781int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
782 struct ksmbd_conn *conn)
Namjae Jeone2f34482021-03-16 10:49:09 +0900783{
784 struct derivation d;
785
786 d.label.iov_base = "SMB2AESCMAC";
787 d.label.iov_len = 12;
788 d.context.iov_base = "SmbSign";
789 d.context.iov_len = 8;
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900790 d.binding = conn->binding;
Namjae Jeone2f34482021-03-16 10:49:09 +0900791
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900792 return generate_smb3signingkey(sess, conn, &d);
Namjae Jeone2f34482021-03-16 10:49:09 +0900793}
794
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900795int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
796 struct ksmbd_conn *conn)
Namjae Jeone2f34482021-03-16 10:49:09 +0900797{
798 struct derivation d;
799
800 d.label.iov_base = "SMBSigningKey";
801 d.label.iov_len = 14;
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900802 if (conn->binding) {
803 struct preauth_session *preauth_sess;
Namjae Jeone2f34482021-03-16 10:49:09 +0900804
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900805 preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
806 if (!preauth_sess)
807 return -ENOENT;
808 d.context.iov_base = preauth_sess->Preauth_HashValue;
809 } else {
810 d.context.iov_base = sess->Preauth_HashValue;
811 }
812 d.context.iov_len = 64;
813 d.binding = conn->binding;
814
815 return generate_smb3signingkey(sess, conn, &d);
Namjae Jeone2f34482021-03-16 10:49:09 +0900816}
817
818struct derivation_twin {
819 struct derivation encryption;
820 struct derivation decryption;
821};
822
823static int generate_smb3encryptionkey(struct ksmbd_session *sess,
Namjae Jeon070fb212021-05-26 17:57:12 +0900824 const struct derivation_twin *ptwin)
Namjae Jeone2f34482021-03-16 10:49:09 +0900825{
826 int rc;
827
828 rc = generate_key(sess, ptwin->encryption.label,
Namjae Jeon070fb212021-05-26 17:57:12 +0900829 ptwin->encryption.context, sess->smb3encryptionkey,
830 SMB3_ENC_DEC_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900831 if (rc)
832 return rc;
833
834 rc = generate_key(sess, ptwin->decryption.label,
Namjae Jeon070fb212021-05-26 17:57:12 +0900835 ptwin->decryption.context,
836 sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900837 if (rc)
838 return rc;
839
840 ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900841 ksmbd_debug(AUTH, "Cipher type %d\n", sess->conn->cipher_type);
Namjae Jeone2f34482021-03-16 10:49:09 +0900842 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
843 ksmbd_debug(AUTH, "Session Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900844 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900845 if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
846 sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
847 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900848 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900849 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900850 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900851 } else {
852 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900853 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900854 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900855 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900856 }
Namjae Jeon876edcc2021-05-26 15:30:04 +0900857 return 0;
Namjae Jeone2f34482021-03-16 10:49:09 +0900858}
859
860int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess)
861{
862 struct derivation_twin twin;
863 struct derivation *d;
864
865 d = &twin.encryption;
866 d->label.iov_base = "SMB2AESCCM";
867 d->label.iov_len = 11;
868 d->context.iov_base = "ServerOut";
869 d->context.iov_len = 10;
870
871 d = &twin.decryption;
872 d->label.iov_base = "SMB2AESCCM";
873 d->label.iov_len = 11;
874 d->context.iov_base = "ServerIn ";
875 d->context.iov_len = 10;
876
877 return generate_smb3encryptionkey(sess, &twin);
878}
879
880int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
881{
882 struct derivation_twin twin;
883 struct derivation *d;
884
885 d = &twin.encryption;
886 d->label.iov_base = "SMBS2CCipherKey";
887 d->label.iov_len = 16;
888 d->context.iov_base = sess->Preauth_HashValue;
889 d->context.iov_len = 64;
890
891 d = &twin.decryption;
892 d->label.iov_base = "SMBC2SCipherKey";
893 d->label.iov_len = 16;
894 d->context.iov_base = sess->Preauth_HashValue;
895 d->context.iov_len = 64;
896
897 return generate_smb3encryptionkey(sess, &twin);
898}
899
Namjae Jeon64b39f42021-03-30 14:25:35 +0900900int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
Namjae Jeon070fb212021-05-26 17:57:12 +0900901 __u8 *pi_hash)
Namjae Jeone2f34482021-03-16 10:49:09 +0900902{
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900903 int rc;
Namjae Jeoncb451722021-11-03 08:08:44 +0900904 struct smb2_hdr *rcv_hdr = smb2_get_msg(buf);
Namjae Jeone2f34482021-03-16 10:49:09 +0900905 char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
Namjae Jeoncb451722021-11-03 08:08:44 +0900906 int msg_size = get_rfc1002_len(buf);
Namjae Jeone2f34482021-03-16 10:49:09 +0900907 struct ksmbd_crypto_ctx *ctx = NULL;
908
Namjae Jeond3cd8c42021-05-26 15:56:18 +0900909 if (conn->preauth_info->Preauth_HashId !=
910 SMB2_PREAUTH_INTEGRITY_SHA512)
911 return -EINVAL;
912
913 ctx = ksmbd_crypto_ctx_find_sha512();
914 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900915 ksmbd_debug(AUTH, "could not alloc sha512\n");
916 return -ENOMEM;
Namjae Jeon64b39f42021-03-30 14:25:35 +0900917 }
Namjae Jeone2f34482021-03-16 10:49:09 +0900918
919 rc = crypto_shash_init(CRYPTO_SHA512(ctx));
920 if (rc) {
921 ksmbd_debug(AUTH, "could not init shashn");
922 goto out;
923 }
924
925 rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
926 if (rc) {
927 ksmbd_debug(AUTH, "could not update with n\n");
928 goto out;
929 }
930
931 rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
932 if (rc) {
933 ksmbd_debug(AUTH, "could not update with n\n");
934 goto out;
935 }
936
937 rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
938 if (rc) {
939 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
940 goto out;
941 }
942out:
943 ksmbd_release_crypto_ctx(ctx);
944 return rc;
945}
946
947int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
Namjae Jeon070fb212021-05-26 17:57:12 +0900948 __u8 *pi_hash)
Namjae Jeone2f34482021-03-16 10:49:09 +0900949{
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900950 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +0900951 struct ksmbd_crypto_ctx *ctx = NULL;
952
953 ctx = ksmbd_crypto_ctx_find_sha256();
954 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900955 ksmbd_debug(AUTH, "could not alloc sha256\n");
956 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900957 }
958
959 rc = crypto_shash_init(CRYPTO_SHA256(ctx));
960 if (rc) {
961 ksmbd_debug(AUTH, "could not init shashn");
962 goto out;
963 }
964
965 rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
966 if (rc) {
967 ksmbd_debug(AUTH, "could not update with n\n");
968 goto out;
969 }
970
971 rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
972 if (rc) {
973 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
974 goto out;
975 }
976out:
977 ksmbd_release_crypto_ctx(ctx);
978 return rc;
979}
980
Namjae Jeon64b39f42021-03-30 14:25:35 +0900981static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
Namjae Jeon070fb212021-05-26 17:57:12 +0900982 int enc, u8 *key)
Namjae Jeone2f34482021-03-16 10:49:09 +0900983{
984 struct ksmbd_session *sess;
985 u8 *ses_enc_key;
986
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900987 sess = ksmbd_session_lookup_all(conn, ses_id);
Namjae Jeone2f34482021-03-16 10:49:09 +0900988 if (!sess)
Namjae Jeon522dcc72021-05-26 15:30:50 +0900989 return -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +0900990
991 ses_enc_key = enc ? sess->smb3encryptionkey :
992 sess->smb3decryptionkey;
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900993 memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900994
995 return 0;
996}
997
998static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
Namjae Jeon070fb212021-05-26 17:57:12 +0900999 unsigned int buflen)
Namjae Jeone2f34482021-03-16 10:49:09 +09001000{
1001 void *addr;
1002
1003 if (is_vmalloc_addr(buf))
1004 addr = vmalloc_to_page(buf);
1005 else
1006 addr = virt_to_page(buf);
1007 sg_set_page(sg, addr, buflen, offset_in_page(buf));
1008}
1009
Namjae Jeon64b39f42021-03-30 14:25:35 +09001010static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
Namjae Jeon070fb212021-05-26 17:57:12 +09001011 u8 *sign)
Namjae Jeone2f34482021-03-16 10:49:09 +09001012{
1013 struct scatterlist *sg;
Namjae Jeon2dd91292021-11-03 08:25:54 +09001014 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
Namjae Jeone2f34482021-03-16 10:49:09 +09001015 int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0;
1016
Namjae Jeon41a78482021-05-26 15:31:37 +09001017 if (!nvec)
1018 return NULL;
1019
Namjae Jeone2f34482021-03-16 10:49:09 +09001020 for (i = 0; i < nvec - 1; i++) {
1021 unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
1022
1023 if (is_vmalloc_addr(iov[i + 1].iov_base)) {
1024 nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
1025 PAGE_SIZE - 1) >> PAGE_SHIFT) -
1026 (kaddr >> PAGE_SHIFT);
Namjae Jeon64b39f42021-03-30 14:25:35 +09001027 } else {
Namjae Jeone2f34482021-03-16 10:49:09 +09001028 nr_entries[i]++;
Namjae Jeon64b39f42021-03-30 14:25:35 +09001029 }
Namjae Jeone2f34482021-03-16 10:49:09 +09001030 total_entries += nr_entries[i];
1031 }
1032
1033 /* Add two entries for transform header and signature */
1034 total_entries += 2;
1035
1036 sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
1037 if (!sg)
1038 return NULL;
1039
1040 sg_init_table(sg, total_entries);
1041 smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1042 for (i = 0; i < nvec - 1; i++) {
1043 void *data = iov[i + 1].iov_base;
1044 int len = iov[i + 1].iov_len;
1045
1046 if (is_vmalloc_addr(data)) {
1047 int j, offset = offset_in_page(data);
1048
1049 for (j = 0; j < nr_entries[i]; j++) {
1050 unsigned int bytes = PAGE_SIZE - offset;
1051
Namjae Jeon08591cc2021-05-26 15:32:26 +09001052 if (!len)
Namjae Jeone2f34482021-03-16 10:49:09 +09001053 break;
1054
1055 if (bytes > len)
1056 bytes = len;
1057
1058 sg_set_page(&sg[sg_idx++],
1059 vmalloc_to_page(data), bytes,
1060 offset_in_page(data));
1061
1062 data += bytes;
1063 len -= bytes;
1064 offset = 0;
1065 }
1066 } else {
1067 sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1068 offset_in_page(data));
1069 }
Namjae Jeone2f34482021-03-16 10:49:09 +09001070 }
1071 smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1072 return sg;
1073}
1074
Namjae Jeon64b39f42021-03-30 14:25:35 +09001075int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
Namjae Jeon070fb212021-05-26 17:57:12 +09001076 unsigned int nvec, int enc)
Namjae Jeone2f34482021-03-16 10:49:09 +09001077{
Namjae Jeon2dd91292021-11-03 08:25:54 +09001078 struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
1079 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
Namjae Jeon03f1c3d2021-05-26 15:34:37 +09001080 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +09001081 struct scatterlist *sg;
1082 u8 sign[SMB2_SIGNATURE_SIZE] = {};
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001083 u8 key[SMB3_ENC_DEC_KEY_SIZE];
Namjae Jeone2f34482021-03-16 10:49:09 +09001084 struct aead_request *req;
1085 char *iv;
1086 unsigned int iv_len;
1087 struct crypto_aead *tfm;
1088 unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1089 struct ksmbd_crypto_ctx *ctx;
1090
1091 rc = ksmbd_get_encryption_key(conn,
1092 le64_to_cpu(tr_hdr->SessionId),
1093 enc,
1094 key);
1095 if (rc) {
Namjae Jeonbde16942021-06-28 15:23:19 +09001096 pr_err("Could not get %scryption key\n", enc ? "en" : "de");
Namjae Jeon27aa6462021-05-26 15:35:26 +09001097 return rc;
Namjae Jeone2f34482021-03-16 10:49:09 +09001098 }
1099
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001100 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1101 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
Namjae Jeone2f34482021-03-16 10:49:09 +09001102 ctx = ksmbd_crypto_ctx_find_gcm();
1103 else
1104 ctx = ksmbd_crypto_ctx_find_ccm();
1105 if (!ctx) {
Namjae Jeonbde16942021-06-28 15:23:19 +09001106 pr_err("crypto alloc failed\n");
Namjae Jeon0e579cd2021-05-26 16:34:56 +09001107 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +09001108 }
1109
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001110 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1111 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
Namjae Jeone2f34482021-03-16 10:49:09 +09001112 tfm = CRYPTO_GCM(ctx);
1113 else
1114 tfm = CRYPTO_CCM(ctx);
1115
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001116 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1117 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1118 rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1119 else
1120 rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +09001121 if (rc) {
Namjae Jeonbde16942021-06-28 15:23:19 +09001122 pr_err("Failed to set aead key %d\n", rc);
Namjae Jeone2f34482021-03-16 10:49:09 +09001123 goto free_ctx;
1124 }
1125
1126 rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1127 if (rc) {
Namjae Jeonbde16942021-06-28 15:23:19 +09001128 pr_err("Failed to set authsize %d\n", rc);
Namjae Jeone2f34482021-03-16 10:49:09 +09001129 goto free_ctx;
1130 }
1131
1132 req = aead_request_alloc(tfm, GFP_KERNEL);
1133 if (!req) {
Namjae Jeone2f34482021-03-16 10:49:09 +09001134 rc = -ENOMEM;
1135 goto free_ctx;
1136 }
1137
1138 if (!enc) {
1139 memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1140 crypt_len += SMB2_SIGNATURE_SIZE;
1141 }
1142
1143 sg = ksmbd_init_sg(iov, nvec, sign);
1144 if (!sg) {
Namjae Jeonbde16942021-06-28 15:23:19 +09001145 pr_err("Failed to init sg\n");
Namjae Jeone2f34482021-03-16 10:49:09 +09001146 rc = -ENOMEM;
1147 goto free_req;
1148 }
1149
1150 iv_len = crypto_aead_ivsize(tfm);
1151 iv = kzalloc(iv_len, GFP_KERNEL);
1152 if (!iv) {
Namjae Jeone2f34482021-03-16 10:49:09 +09001153 rc = -ENOMEM;
1154 goto free_sg;
1155 }
1156
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001157 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1158 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1159 memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
Namjae Jeon64b39f42021-03-30 14:25:35 +09001160 } else {
Namjae Jeone2f34482021-03-16 10:49:09 +09001161 iv[0] = 3;
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001162 memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
Namjae Jeone2f34482021-03-16 10:49:09 +09001163 }
1164
1165 aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1166 aead_request_set_ad(req, assoc_data_len);
1167 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1168
1169 if (enc)
1170 rc = crypto_aead_encrypt(req);
1171 else
1172 rc = crypto_aead_decrypt(req);
Namjae Jeon73b8b082021-05-26 15:53:26 +09001173 if (rc)
1174 goto free_iv;
1175
1176 if (enc)
Namjae Jeone2f34482021-03-16 10:49:09 +09001177 memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1178
Namjae Jeon73b8b082021-05-26 15:53:26 +09001179free_iv:
Namjae Jeone2f34482021-03-16 10:49:09 +09001180 kfree(iv);
1181free_sg:
1182 kfree(sg);
1183free_req:
1184 kfree(req);
1185free_ctx:
1186 ksmbd_release_crypto_ctx(ctx);
1187 return rc;
1188}