blob: 30a92ddc181747e3becf8a419220eab003fffb04 [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 Jeone2f34482021-03-16 10:49:09 +090032
33/*
34 * Fixed format data defining GSS header and fixed string
35 * "not_defined_in_RFC4178@please_ignore".
36 * So sec blob data in neg phase could be generated statically.
37 */
38static char NEGOTIATE_GSS_HEADER[AUTH_GSS_LENGTH] = {
39#ifdef CONFIG_SMB_SERVER_KERBEROS5
40 0x60, 0x5e, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
41 0x05, 0x02, 0xa0, 0x54, 0x30, 0x52, 0xa0, 0x24,
42 0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
43 0xf7, 0x12, 0x01, 0x02, 0x02, 0x06, 0x09, 0x2a,
44 0x86, 0x48, 0x82, 0xf7, 0x12, 0x01, 0x02, 0x02,
45 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
46 0x37, 0x02, 0x02, 0x0a, 0xa3, 0x2a, 0x30, 0x28,
47 0xa0, 0x26, 0x1b, 0x24, 0x6e, 0x6f, 0x74, 0x5f,
48 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f,
49 0x69, 0x6e, 0x5f, 0x52, 0x46, 0x43, 0x34, 0x31,
50 0x37, 0x38, 0x40, 0x70, 0x6c, 0x65, 0x61, 0x73,
51 0x65, 0x5f, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65
52#else
53 0x60, 0x48, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
54 0x05, 0x02, 0xa0, 0x3e, 0x30, 0x3c, 0xa0, 0x0e,
55 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
56 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa3, 0x2a,
57 0x30, 0x28, 0xa0, 0x26, 0x1b, 0x24, 0x6e, 0x6f,
58 0x74, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65,
59 0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x52, 0x46, 0x43,
60 0x34, 0x31, 0x37, 0x38, 0x40, 0x70, 0x6c, 0x65,
61 0x61, 0x73, 0x65, 0x5f, 0x69, 0x67, 0x6e, 0x6f,
62 0x72, 0x65
63#endif
64};
65
Namjae Jeone2f34482021-03-16 10:49:09 +090066void ksmbd_copy_gss_neg_header(void *buf)
67{
68 memcpy(buf, NEGOTIATE_GSS_HEADER, AUTH_GSS_LENGTH);
69}
70
Namjae Jeone2f34482021-03-16 10:49:09 +090071/**
72 * ksmbd_gen_sess_key() - function to generate session key
73 * @sess: session of connection
74 * @hash: source hash value to be used for find session key
75 * @hmac: source hmac value to be used for finding session key
76 *
77 */
Namjae Jeon64b39f42021-03-30 14:25:35 +090078static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
Namjae Jeon070fb212021-05-26 17:57:12 +090079 char *hmac)
Namjae Jeone2f34482021-03-16 10:49:09 +090080{
81 struct ksmbd_crypto_ctx *ctx;
Namjae Jeon0e579cd2021-05-26 16:34:56 +090082 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +090083
84 ctx = ksmbd_crypto_ctx_find_hmacmd5();
Namjae Jeon0e579cd2021-05-26 16:34:56 +090085 if (!ctx) {
86 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
87 return -ENOMEM;
88 }
Namjae Jeone2f34482021-03-16 10:49:09 +090089
90 rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
91 hash,
92 CIFS_HMAC_MD5_HASH_SIZE);
93 if (rc) {
94 ksmbd_debug(AUTH, "hmacmd5 set key fail error %d\n", rc);
95 goto out;
96 }
97
98 rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
99 if (rc) {
100 ksmbd_debug(AUTH, "could not init hmacmd5 error %d\n", rc);
101 goto out;
102 }
103
104 rc = crypto_shash_update(CRYPTO_HMACMD5(ctx),
105 hmac,
106 SMB2_NTLMV2_SESSKEY_SIZE);
107 if (rc) {
Namjae Jeon070fb212021-05-26 17:57:12 +0900108 ksmbd_debug(AUTH, "Could not update with response error %d\n", rc);
Namjae Jeone2f34482021-03-16 10:49:09 +0900109 goto out;
110 }
111
112 rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
113 if (rc) {
Namjae Jeon070fb212021-05-26 17:57:12 +0900114 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n", rc);
Namjae Jeone2f34482021-03-16 10:49:09 +0900115 goto out;
116 }
117
118out:
119 ksmbd_release_crypto_ctx(ctx);
120 return rc;
121}
122
123static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
Namjae Jeon070fb212021-05-26 17:57:12 +0900124 char *dname)
Namjae Jeone2f34482021-03-16 10:49:09 +0900125{
Namjae Jeona2d0b502021-05-26 16:37:05 +0900126 int ret, len, conv_len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900127 wchar_t *domain = NULL;
128 __le16 *uniname = NULL;
129 struct ksmbd_crypto_ctx *ctx;
130
131 ctx = ksmbd_crypto_ctx_find_hmacmd5();
132 if (!ctx) {
133 ksmbd_debug(AUTH, "can't generate ntlmv2 hash\n");
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900134 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900135 }
136
137 ret = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
138 user_passkey(sess->user),
139 CIFS_ENCPWD_SIZE);
140 if (ret) {
141 ksmbd_debug(AUTH, "Could not set NT Hash as a key\n");
142 goto out;
143 }
144
145 ret = crypto_shash_init(CRYPTO_HMACMD5(ctx));
146 if (ret) {
147 ksmbd_debug(AUTH, "could not init hmacmd5\n");
148 goto out;
149 }
150
151 /* convert user_name to unicode */
152 len = strlen(user_name(sess->user));
153 uniname = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
154 if (!uniname) {
155 ret = -ENOMEM;
156 goto out;
157 }
158
Namjae Jeona2d0b502021-05-26 16:37:05 +0900159 conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
Namjae Jeon070fb212021-05-26 17:57:12 +0900160 sess->conn->local_nls);
Namjae Jeona2d0b502021-05-26 16:37:05 +0900161 if (conv_len < 0 || conv_len > len) {
162 ret = -EINVAL;
163 goto out;
Namjae Jeone2f34482021-03-16 10:49:09 +0900164 }
Namjae Jeona2d0b502021-05-26 16:37:05 +0900165 UniStrupr(uniname);
Namjae Jeone2f34482021-03-16 10:49:09 +0900166
167 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
168 (char *)uniname,
Namjae Jeona2d0b502021-05-26 16:37:05 +0900169 UNICODE_LEN(conv_len));
Namjae Jeone2f34482021-03-16 10:49:09 +0900170 if (ret) {
171 ksmbd_debug(AUTH, "Could not update with user\n");
172 goto out;
173 }
174
175 /* Convert domain name or conn name to unicode and uppercase */
176 len = strlen(dname);
177 domain = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
178 if (!domain) {
179 ret = -ENOMEM;
180 goto out;
181 }
182
Namjae Jeona2d0b502021-05-26 16:37:05 +0900183 conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
Namjae Jeon070fb212021-05-26 17:57:12 +0900184 sess->conn->local_nls);
Namjae Jeona2d0b502021-05-26 16:37:05 +0900185 if (conv_len < 0 || conv_len > len) {
186 ret = -EINVAL;
187 goto out;
188 }
Namjae Jeone2f34482021-03-16 10:49:09 +0900189
190 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
191 (char *)domain,
Namjae Jeona2d0b502021-05-26 16:37:05 +0900192 UNICODE_LEN(conv_len));
Namjae Jeone2f34482021-03-16 10:49:09 +0900193 if (ret) {
194 ksmbd_debug(AUTH, "Could not update with domain\n");
195 goto out;
196 }
197
198 ret = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_hash);
Namjae Jeone2f34482021-03-16 10:49:09 +0900199 if (ret)
200 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
Namjae Jeon7e38ea22021-05-26 15:27:11 +0900201out:
Namjae Jeone2f34482021-03-16 10:49:09 +0900202 kfree(uniname);
203 kfree(domain);
204 ksmbd_release_crypto_ctx(ctx);
205 return ret;
206}
207
208/**
Namjae Jeone2f34482021-03-16 10:49:09 +0900209 * ksmbd_auth_ntlmv2() - NTLMv2 authentication handler
210 * @sess: session of connection
211 * @ntlmv2: NTLMv2 challenge response
212 * @blen: NTLMv2 blob length
213 * @domain_name: domain name
214 *
215 * Return: 0 on success, error number on error
216 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900217int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
Namjae Jeon070fb212021-05-26 17:57:12 +0900218 int blen, char *domain_name)
Namjae Jeone2f34482021-03-16 10:49:09 +0900219{
220 char ntlmv2_hash[CIFS_ENCPWD_SIZE];
221 char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
222 struct ksmbd_crypto_ctx *ctx;
223 char *construct = NULL;
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900224 int rc, len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900225
226 ctx = ksmbd_crypto_ctx_find_hmacmd5();
227 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900228 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
229 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900230 }
231
232 rc = calc_ntlmv2_hash(sess, ntlmv2_hash, domain_name);
233 if (rc) {
234 ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
235 goto out;
236 }
237
238 rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
239 ntlmv2_hash,
240 CIFS_HMAC_MD5_HASH_SIZE);
241 if (rc) {
242 ksmbd_debug(AUTH, "Could not set NTLMV2 Hash as a key\n");
243 goto out;
244 }
245
246 rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
247 if (rc) {
248 ksmbd_debug(AUTH, "Could not init hmacmd5\n");
249 goto out;
250 }
251
252 len = CIFS_CRYPTO_KEY_SIZE + blen;
253 construct = kzalloc(len, GFP_KERNEL);
254 if (!construct) {
255 rc = -ENOMEM;
256 goto out;
257 }
258
259 memcpy(construct, sess->ntlmssp.cryptkey, CIFS_CRYPTO_KEY_SIZE);
Namjae Jeon192cc732021-05-26 15:28:48 +0900260 memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
Namjae Jeone2f34482021-03-16 10:49:09 +0900261
262 rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
263 if (rc) {
264 ksmbd_debug(AUTH, "Could not update with response\n");
265 goto out;
266 }
267
268 rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_rsp);
269 if (rc) {
270 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
271 goto out;
272 }
273
274 rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
275 if (rc) {
276 ksmbd_debug(AUTH, "Could not generate sess key\n");
277 goto out;
278 }
279
Namjae Jeonb72802a2021-05-26 15:29:24 +0900280 if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
281 rc = -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +0900282out:
283 ksmbd_release_crypto_ctx(ctx);
284 kfree(construct);
285 return rc;
286}
287
288/**
Namjae Jeone2f34482021-03-16 10:49:09 +0900289 * ksmbd_decode_ntlmssp_auth_blob() - helper function to construct
290 * authenticate blob
291 * @authblob: authenticate blob source pointer
292 * @usr: user details
293 * @sess: session of connection
294 *
295 * Return: 0 on success, error number on error
296 */
297int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
Namjae Jeon070fb212021-05-26 17:57:12 +0900298 int blob_len, struct ksmbd_session *sess)
Namjae Jeone2f34482021-03-16 10:49:09 +0900299{
300 char *domain_name;
Marios Makassikis0d994cd2021-10-19 17:39:38 +0200301 unsigned int nt_off, dn_off;
302 unsigned short nt_len, dn_len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900303 int ret;
304
305 if (blob_len < sizeof(struct authenticate_message)) {
306 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900307 blob_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900308 return -EINVAL;
309 }
310
311 if (memcmp(authblob->Signature, "NTLMSSP", 8)) {
312 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900313 authblob->Signature);
Namjae Jeone2f34482021-03-16 10:49:09 +0900314 return -EINVAL;
315 }
316
Namjae Jeone2f34482021-03-16 10:49:09 +0900317 nt_off = le32_to_cpu(authblob->NtChallengeResponse.BufferOffset);
318 nt_len = le16_to_cpu(authblob->NtChallengeResponse.Length);
Marios Makassikis0d994cd2021-10-19 17:39:38 +0200319 dn_off = le32_to_cpu(authblob->DomainName.BufferOffset);
320 dn_len = le16_to_cpu(authblob->DomainName.Length);
321
322 if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len)
323 return -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +0900324
Namjae Jeone2f34482021-03-16 10:49:09 +0900325 /* TODO : use domain name that imported from configuration file */
Marios Makassikis0d994cd2021-10-19 17:39:38 +0200326 domain_name = smb_strndup_from_utf16((const char *)authblob + dn_off,
327 dn_len, true, sess->conn->local_nls);
Namjae Jeone2f34482021-03-16 10:49:09 +0900328 if (IS_ERR(domain_name))
329 return PTR_ERR(domain_name);
330
331 /* process NTLMv2 authentication */
332 ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900333 domain_name);
334 ret = ksmbd_auth_ntlmv2(sess, (struct ntlmv2_resp *)((char *)authblob + nt_off),
335 nt_len - CIFS_ENCPWD_SIZE,
336 domain_name);
Namjae Jeone2f34482021-03-16 10:49:09 +0900337 kfree(domain_name);
338 return ret;
339}
340
341/**
342 * ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
343 * negotiate blob
344 * @negblob: negotiate blob source pointer
345 * @rsp: response header pointer to be updated
346 * @sess: session of connection
347 *
348 */
349int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
Namjae Jeon070fb212021-05-26 17:57:12 +0900350 int blob_len, struct ksmbd_session *sess)
Namjae Jeone2f34482021-03-16 10:49:09 +0900351{
352 if (blob_len < sizeof(struct negotiate_message)) {
353 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900354 blob_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900355 return -EINVAL;
356 }
357
358 if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
359 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900360 negblob->Signature);
Namjae Jeone2f34482021-03-16 10:49:09 +0900361 return -EINVAL;
362 }
363
364 sess->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
365 return 0;
366}
367
368/**
369 * ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
370 * challenge blob
371 * @chgblob: challenge blob source pointer to initialize
372 * @rsp: response header pointer to be updated
373 * @sess: session of connection
374 *
375 */
376unsigned int
377ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
Namjae Jeon070fb212021-05-26 17:57:12 +0900378 struct ksmbd_session *sess)
Namjae Jeone2f34482021-03-16 10:49:09 +0900379{
380 struct target_info *tinfo;
381 wchar_t *name;
382 __u8 *target_name;
Namjae Jeon152de8c2021-05-29 07:59:40 +0900383 unsigned int flags, blob_off, blob_len, type, target_info_len = 0;
384 int len, uni_len, conv_len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900385 int cflags = sess->ntlmssp.client_flags;
386
387 memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
388 chgblob->MessageType = NtLmChallenge;
389
390 flags = NTLMSSP_NEGOTIATE_UNICODE |
391 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
392 NTLMSSP_NEGOTIATE_TARGET_INFO;
393
394 if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
395 flags |= NTLMSSP_NEGOTIATE_SIGN;
396 flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
Namjae Jeon70478052021-05-26 16:36:15 +0900397 NTLMSSP_NEGOTIATE_56);
Namjae Jeone2f34482021-03-16 10:49:09 +0900398 }
399
400 if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
401 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
402
403 if (cflags & NTLMSSP_REQUEST_TARGET)
404 flags |= NTLMSSP_REQUEST_TARGET;
405
406 if (sess->conn->use_spnego &&
Namjae Jeon64b39f42021-03-30 14:25:35 +0900407 (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
Namjae Jeone2f34482021-03-16 10:49:09 +0900408 flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
409
410 chgblob->NegotiateFlags = cpu_to_le32(flags);
411 len = strlen(ksmbd_netbios_name());
Namjae Jeona2d0b502021-05-26 16:37:05 +0900412 name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
Namjae Jeone2f34482021-03-16 10:49:09 +0900413 if (!name)
414 return -ENOMEM;
415
Namjae Jeona2d0b502021-05-26 16:37:05 +0900416 conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
Namjae Jeon070fb212021-05-26 17:57:12 +0900417 sess->conn->local_nls);
Namjae Jeona2d0b502021-05-26 16:37:05 +0900418 if (conv_len < 0 || conv_len > len) {
419 kfree(name);
420 return -EINVAL;
421 }
422
423 uni_len = UNICODE_LEN(conv_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900424
425 blob_off = sizeof(struct challenge_message);
Namjae Jeona2d0b502021-05-26 16:37:05 +0900426 blob_len = blob_off + uni_len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900427
Namjae Jeona2d0b502021-05-26 16:37:05 +0900428 chgblob->TargetName.Length = cpu_to_le16(uni_len);
429 chgblob->TargetName.MaximumLength = cpu_to_le16(uni_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900430 chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
431
432 /* Initialize random conn challenge */
433 get_random_bytes(sess->ntlmssp.cryptkey, sizeof(__u64));
434 memcpy(chgblob->Challenge, sess->ntlmssp.cryptkey,
Namjae Jeon070fb212021-05-26 17:57:12 +0900435 CIFS_CRYPTO_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900436
437 /* Add Target Information to security buffer */
438 chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
439
440 target_name = (__u8 *)chgblob + blob_off;
Namjae Jeona2d0b502021-05-26 16:37:05 +0900441 memcpy(target_name, name, uni_len);
442 tinfo = (struct target_info *)(target_name + uni_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900443
444 chgblob->TargetInfoArray.Length = 0;
445 /* Add target info list for NetBIOS/DNS settings */
446 for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
Namjae Jeon70478052021-05-26 16:36:15 +0900447 type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
Namjae Jeone2f34482021-03-16 10:49:09 +0900448 tinfo->Type = cpu_to_le16(type);
Namjae Jeona2d0b502021-05-26 16:37:05 +0900449 tinfo->Length = cpu_to_le16(uni_len);
450 memcpy(tinfo->Content, name, uni_len);
451 tinfo = (struct target_info *)((char *)tinfo + 4 + uni_len);
452 target_info_len += 4 + uni_len;
Namjae Jeone2f34482021-03-16 10:49:09 +0900453 }
454
455 /* Add terminator subblock */
456 tinfo->Type = 0;
457 tinfo->Length = 0;
458 target_info_len += 4;
459
460 chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
461 chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
462 blob_len += target_info_len;
463 kfree(name);
464 ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
465 return blob_len;
466}
467
468#ifdef CONFIG_SMB_SERVER_KERBEROS5
Namjae Jeon64b39f42021-03-30 14:25:35 +0900469int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
Namjae Jeon070fb212021-05-26 17:57:12 +0900470 int in_len, char *out_blob, int *out_len)
Namjae Jeone2f34482021-03-16 10:49:09 +0900471{
472 struct ksmbd_spnego_authen_response *resp;
473 struct ksmbd_user *user = NULL;
474 int retval;
475
476 resp = ksmbd_ipc_spnego_authen_request(in_blob, in_len);
477 if (!resp) {
478 ksmbd_debug(AUTH, "SPNEGO_AUTHEN_REQUEST failure\n");
479 return -EINVAL;
480 }
481
482 if (!(resp->login_response.status & KSMBD_USER_FLAG_OK)) {
483 ksmbd_debug(AUTH, "krb5 authentication failure\n");
484 retval = -EPERM;
485 goto out;
486 }
487
488 if (*out_len <= resp->spnego_blob_len) {
489 ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900490 *out_len, resp->spnego_blob_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900491 retval = -EINVAL;
492 goto out;
493 }
494
495 if (resp->session_key_len > sizeof(sess->sess_key)) {
496 ksmbd_debug(AUTH, "session key is too long\n");
497 retval = -EINVAL;
498 goto out;
499 }
500
501 user = ksmbd_alloc_user(&resp->login_response);
502 if (!user) {
503 ksmbd_debug(AUTH, "login failure\n");
504 retval = -ENOMEM;
505 goto out;
506 }
507 sess->user = user;
508
509 memcpy(sess->sess_key, resp->payload, resp->session_key_len);
510 memcpy(out_blob, resp->payload + resp->session_key_len,
Namjae Jeon070fb212021-05-26 17:57:12 +0900511 resp->spnego_blob_len);
Namjae Jeone2f34482021-03-16 10:49:09 +0900512 *out_len = resp->spnego_blob_len;
513 retval = 0;
514out:
Namjae Jeon79f6b112021-04-02 12:47:14 +0900515 kvfree(resp);
Namjae Jeone2f34482021-03-16 10:49:09 +0900516 return retval;
517}
518#else
Namjae Jeon64b39f42021-03-30 14:25:35 +0900519int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
Namjae Jeon070fb212021-05-26 17:57:12 +0900520 int in_len, char *out_blob, int *out_len)
Namjae Jeone2f34482021-03-16 10:49:09 +0900521{
522 return -EOPNOTSUPP;
523}
524#endif
525
526/**
527 * ksmbd_sign_smb2_pdu() - function to generate packet signing
528 * @conn: connection
529 * @key: signing key
530 * @iov: buffer iov array
531 * @n_vec: number of iovecs
532 * @sig: signature value generated for client request packet
533 *
534 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900535int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
Namjae Jeon070fb212021-05-26 17:57:12 +0900536 int n_vec, char *sig)
Namjae Jeone2f34482021-03-16 10:49:09 +0900537{
538 struct ksmbd_crypto_ctx *ctx;
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900539 int rc, i;
Namjae Jeone2f34482021-03-16 10:49:09 +0900540
541 ctx = ksmbd_crypto_ctx_find_hmacsha256();
542 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900543 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
544 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900545 }
546
547 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
548 key,
549 SMB2_NTLMV2_SESSKEY_SIZE);
550 if (rc)
551 goto out;
552
553 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
554 if (rc) {
555 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
556 goto out;
557 }
558
559 for (i = 0; i < n_vec; i++) {
560 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
561 iov[i].iov_base,
562 iov[i].iov_len);
563 if (rc) {
564 ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
565 goto out;
566 }
567 }
568
569 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
570 if (rc)
571 ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
572out:
573 ksmbd_release_crypto_ctx(ctx);
574 return rc;
575}
576
577/**
578 * ksmbd_sign_smb3_pdu() - function to generate packet signing
579 * @conn: connection
580 * @key: signing key
581 * @iov: buffer iov array
582 * @n_vec: number of iovecs
583 * @sig: signature value generated for client request packet
584 *
585 */
Namjae Jeon64b39f42021-03-30 14:25:35 +0900586int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
Namjae Jeon070fb212021-05-26 17:57:12 +0900587 int n_vec, char *sig)
Namjae Jeone2f34482021-03-16 10:49:09 +0900588{
589 struct ksmbd_crypto_ctx *ctx;
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900590 int rc, i;
Namjae Jeone2f34482021-03-16 10:49:09 +0900591
592 ctx = ksmbd_crypto_ctx_find_cmacaes();
593 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900594 ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
595 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900596 }
597
598 rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
599 key,
600 SMB2_CMACAES_SIZE);
601 if (rc)
602 goto out;
603
604 rc = crypto_shash_init(CRYPTO_CMACAES(ctx));
605 if (rc) {
606 ksmbd_debug(AUTH, "cmaces init error %d\n", rc);
607 goto out;
608 }
609
610 for (i = 0; i < n_vec; i++) {
611 rc = crypto_shash_update(CRYPTO_CMACAES(ctx),
612 iov[i].iov_base,
613 iov[i].iov_len);
614 if (rc) {
615 ksmbd_debug(AUTH, "cmaces update error %d\n", rc);
616 goto out;
617 }
618 }
619
620 rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig);
621 if (rc)
622 ksmbd_debug(AUTH, "cmaces generation error %d\n", rc);
623out:
624 ksmbd_release_crypto_ctx(ctx);
625 return rc;
626}
627
628struct derivation {
629 struct kvec label;
630 struct kvec context;
631 bool binding;
632};
633
634static int generate_key(struct ksmbd_session *sess, struct kvec label,
Namjae Jeon070fb212021-05-26 17:57:12 +0900635 struct kvec context, __u8 *key, unsigned int key_size)
Namjae Jeone2f34482021-03-16 10:49:09 +0900636{
637 unsigned char zero = 0x0;
638 __u8 i[4] = {0, 0, 0, 1};
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900639 __u8 L128[4] = {0, 0, 0, 128};
640 __u8 L256[4] = {0, 0, 1, 0};
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900641 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +0900642 unsigned char prfhash[SMB2_HMACSHA256_SIZE];
643 unsigned char *hashptr = prfhash;
644 struct ksmbd_crypto_ctx *ctx;
645
646 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
647 memset(key, 0x0, key_size);
648
649 ctx = ksmbd_crypto_ctx_find_hmacsha256();
650 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900651 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
652 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900653 }
654
655 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
656 sess->sess_key,
657 SMB2_NTLMV2_SESSKEY_SIZE);
658 if (rc)
659 goto smb3signkey_ret;
660
661 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
662 if (rc) {
663 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
664 goto smb3signkey_ret;
665 }
666
667 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
668 if (rc) {
669 ksmbd_debug(AUTH, "could not update with n\n");
670 goto smb3signkey_ret;
671 }
672
673 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
674 label.iov_base,
675 label.iov_len);
676 if (rc) {
677 ksmbd_debug(AUTH, "could not update with label\n");
678 goto smb3signkey_ret;
679 }
680
681 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
682 if (rc) {
683 ksmbd_debug(AUTH, "could not update with zero\n");
684 goto smb3signkey_ret;
685 }
686
687 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
688 context.iov_base,
689 context.iov_len);
690 if (rc) {
691 ksmbd_debug(AUTH, "could not update with context\n");
692 goto smb3signkey_ret;
693 }
694
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900695 if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
696 sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
697 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
698 else
699 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
Namjae Jeone2f34482021-03-16 10:49:09 +0900700 if (rc) {
701 ksmbd_debug(AUTH, "could not update with L\n");
702 goto smb3signkey_ret;
703 }
704
705 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
706 if (rc) {
707 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900708 rc);
Namjae Jeone2f34482021-03-16 10:49:09 +0900709 goto smb3signkey_ret;
710 }
711
712 memcpy(key, hashptr, key_size);
713
714smb3signkey_ret:
715 ksmbd_release_crypto_ctx(ctx);
716 return rc;
717}
718
719static int generate_smb3signingkey(struct ksmbd_session *sess,
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900720 struct ksmbd_conn *conn,
Namjae Jeon070fb212021-05-26 17:57:12 +0900721 const struct derivation *signing)
Namjae Jeone2f34482021-03-16 10:49:09 +0900722{
723 int rc;
724 struct channel *chann;
725 char *key;
726
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900727 chann = lookup_chann_list(sess, conn);
Namjae Jeone2f34482021-03-16 10:49:09 +0900728 if (!chann)
729 return 0;
730
731 if (sess->conn->dialect >= SMB30_PROT_ID && signing->binding)
732 key = chann->smb3signingkey;
733 else
734 key = sess->smb3signingkey;
735
736 rc = generate_key(sess, signing->label, signing->context, key,
Namjae Jeon070fb212021-05-26 17:57:12 +0900737 SMB3_SIGN_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900738 if (rc)
739 return rc;
740
741 if (!(sess->conn->dialect >= SMB30_PROT_ID && signing->binding))
742 memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
743
744 ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
745 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
746 ksmbd_debug(AUTH, "Session Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900747 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
Namjae Jeone2f34482021-03-16 10:49:09 +0900748 ksmbd_debug(AUTH, "Signing Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900749 SMB3_SIGN_KEY_SIZE, key);
Namjae Jeon876edcc2021-05-26 15:30:04 +0900750 return 0;
Namjae Jeone2f34482021-03-16 10:49:09 +0900751}
752
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900753int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
754 struct ksmbd_conn *conn)
Namjae Jeone2f34482021-03-16 10:49:09 +0900755{
756 struct derivation d;
757
758 d.label.iov_base = "SMB2AESCMAC";
759 d.label.iov_len = 12;
760 d.context.iov_base = "SmbSign";
761 d.context.iov_len = 8;
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900762 d.binding = conn->binding;
Namjae Jeone2f34482021-03-16 10:49:09 +0900763
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900764 return generate_smb3signingkey(sess, conn, &d);
Namjae Jeone2f34482021-03-16 10:49:09 +0900765}
766
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900767int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
768 struct ksmbd_conn *conn)
Namjae Jeone2f34482021-03-16 10:49:09 +0900769{
770 struct derivation d;
771
772 d.label.iov_base = "SMBSigningKey";
773 d.label.iov_len = 14;
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900774 if (conn->binding) {
775 struct preauth_session *preauth_sess;
Namjae Jeone2f34482021-03-16 10:49:09 +0900776
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900777 preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
778 if (!preauth_sess)
779 return -ENOENT;
780 d.context.iov_base = preauth_sess->Preauth_HashValue;
781 } else {
782 d.context.iov_base = sess->Preauth_HashValue;
783 }
784 d.context.iov_len = 64;
785 d.binding = conn->binding;
786
787 return generate_smb3signingkey(sess, conn, &d);
Namjae Jeone2f34482021-03-16 10:49:09 +0900788}
789
790struct derivation_twin {
791 struct derivation encryption;
792 struct derivation decryption;
793};
794
795static int generate_smb3encryptionkey(struct ksmbd_session *sess,
Namjae Jeon070fb212021-05-26 17:57:12 +0900796 const struct derivation_twin *ptwin)
Namjae Jeone2f34482021-03-16 10:49:09 +0900797{
798 int rc;
799
800 rc = generate_key(sess, ptwin->encryption.label,
Namjae Jeon070fb212021-05-26 17:57:12 +0900801 ptwin->encryption.context, sess->smb3encryptionkey,
802 SMB3_ENC_DEC_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900803 if (rc)
804 return rc;
805
806 rc = generate_key(sess, ptwin->decryption.label,
Namjae Jeon070fb212021-05-26 17:57:12 +0900807 ptwin->decryption.context,
808 sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900809 if (rc)
810 return rc;
811
812 ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900813 ksmbd_debug(AUTH, "Cipher type %d\n", sess->conn->cipher_type);
Namjae Jeone2f34482021-03-16 10:49:09 +0900814 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
815 ksmbd_debug(AUTH, "Session Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900816 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900817 if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
818 sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
819 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900820 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900821 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900822 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900823 } else {
824 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900825 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900826 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
Namjae Jeon070fb212021-05-26 17:57:12 +0900827 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900828 }
Namjae Jeon876edcc2021-05-26 15:30:04 +0900829 return 0;
Namjae Jeone2f34482021-03-16 10:49:09 +0900830}
831
832int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess)
833{
834 struct derivation_twin twin;
835 struct derivation *d;
836
837 d = &twin.encryption;
838 d->label.iov_base = "SMB2AESCCM";
839 d->label.iov_len = 11;
840 d->context.iov_base = "ServerOut";
841 d->context.iov_len = 10;
842
843 d = &twin.decryption;
844 d->label.iov_base = "SMB2AESCCM";
845 d->label.iov_len = 11;
846 d->context.iov_base = "ServerIn ";
847 d->context.iov_len = 10;
848
849 return generate_smb3encryptionkey(sess, &twin);
850}
851
852int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
853{
854 struct derivation_twin twin;
855 struct derivation *d;
856
857 d = &twin.encryption;
858 d->label.iov_base = "SMBS2CCipherKey";
859 d->label.iov_len = 16;
860 d->context.iov_base = sess->Preauth_HashValue;
861 d->context.iov_len = 64;
862
863 d = &twin.decryption;
864 d->label.iov_base = "SMBC2SCipherKey";
865 d->label.iov_len = 16;
866 d->context.iov_base = sess->Preauth_HashValue;
867 d->context.iov_len = 64;
868
869 return generate_smb3encryptionkey(sess, &twin);
870}
871
Namjae Jeon64b39f42021-03-30 14:25:35 +0900872int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
Namjae Jeon070fb212021-05-26 17:57:12 +0900873 __u8 *pi_hash)
Namjae Jeone2f34482021-03-16 10:49:09 +0900874{
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900875 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +0900876 struct smb2_hdr *rcv_hdr = (struct smb2_hdr *)buf;
877 char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
878 int msg_size = be32_to_cpu(rcv_hdr->smb2_buf_length);
879 struct ksmbd_crypto_ctx *ctx = NULL;
880
Namjae Jeond3cd8c42021-05-26 15:56:18 +0900881 if (conn->preauth_info->Preauth_HashId !=
882 SMB2_PREAUTH_INTEGRITY_SHA512)
883 return -EINVAL;
884
885 ctx = ksmbd_crypto_ctx_find_sha512();
886 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900887 ksmbd_debug(AUTH, "could not alloc sha512\n");
888 return -ENOMEM;
Namjae Jeon64b39f42021-03-30 14:25:35 +0900889 }
Namjae Jeone2f34482021-03-16 10:49:09 +0900890
891 rc = crypto_shash_init(CRYPTO_SHA512(ctx));
892 if (rc) {
893 ksmbd_debug(AUTH, "could not init shashn");
894 goto out;
895 }
896
897 rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
898 if (rc) {
899 ksmbd_debug(AUTH, "could not update with n\n");
900 goto out;
901 }
902
903 rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
904 if (rc) {
905 ksmbd_debug(AUTH, "could not update with n\n");
906 goto out;
907 }
908
909 rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
910 if (rc) {
911 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
912 goto out;
913 }
914out:
915 ksmbd_release_crypto_ctx(ctx);
916 return rc;
917}
918
919int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
Namjae Jeon070fb212021-05-26 17:57:12 +0900920 __u8 *pi_hash)
Namjae Jeone2f34482021-03-16 10:49:09 +0900921{
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900922 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +0900923 struct ksmbd_crypto_ctx *ctx = NULL;
924
925 ctx = ksmbd_crypto_ctx_find_sha256();
926 if (!ctx) {
Namjae Jeon0e579cd2021-05-26 16:34:56 +0900927 ksmbd_debug(AUTH, "could not alloc sha256\n");
928 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +0900929 }
930
931 rc = crypto_shash_init(CRYPTO_SHA256(ctx));
932 if (rc) {
933 ksmbd_debug(AUTH, "could not init shashn");
934 goto out;
935 }
936
937 rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
938 if (rc) {
939 ksmbd_debug(AUTH, "could not update with n\n");
940 goto out;
941 }
942
943 rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
944 if (rc) {
945 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
946 goto out;
947 }
948out:
949 ksmbd_release_crypto_ctx(ctx);
950 return rc;
951}
952
Namjae Jeon64b39f42021-03-30 14:25:35 +0900953static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
Namjae Jeon070fb212021-05-26 17:57:12 +0900954 int enc, u8 *key)
Namjae Jeone2f34482021-03-16 10:49:09 +0900955{
956 struct ksmbd_session *sess;
957 u8 *ses_enc_key;
958
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900959 sess = ksmbd_session_lookup_all(conn, ses_id);
Namjae Jeone2f34482021-03-16 10:49:09 +0900960 if (!sess)
Namjae Jeon522dcc72021-05-26 15:30:50 +0900961 return -EINVAL;
Namjae Jeone2f34482021-03-16 10:49:09 +0900962
963 ses_enc_key = enc ? sess->smb3encryptionkey :
964 sess->smb3decryptionkey;
Namjae Jeon5a0ca772021-05-06 11:43:37 +0900965 memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +0900966
967 return 0;
968}
969
970static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
Namjae Jeon070fb212021-05-26 17:57:12 +0900971 unsigned int buflen)
Namjae Jeone2f34482021-03-16 10:49:09 +0900972{
973 void *addr;
974
975 if (is_vmalloc_addr(buf))
976 addr = vmalloc_to_page(buf);
977 else
978 addr = virt_to_page(buf);
979 sg_set_page(sg, addr, buflen, offset_in_page(buf));
980}
981
Namjae Jeon64b39f42021-03-30 14:25:35 +0900982static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
Namjae Jeon070fb212021-05-26 17:57:12 +0900983 u8 *sign)
Namjae Jeone2f34482021-03-16 10:49:09 +0900984{
985 struct scatterlist *sg;
986 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
987 int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0;
988
Namjae Jeon41a78482021-05-26 15:31:37 +0900989 if (!nvec)
990 return NULL;
991
Namjae Jeone2f34482021-03-16 10:49:09 +0900992 for (i = 0; i < nvec - 1; i++) {
993 unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
994
995 if (is_vmalloc_addr(iov[i + 1].iov_base)) {
996 nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
997 PAGE_SIZE - 1) >> PAGE_SHIFT) -
998 (kaddr >> PAGE_SHIFT);
Namjae Jeon64b39f42021-03-30 14:25:35 +0900999 } else {
Namjae Jeone2f34482021-03-16 10:49:09 +09001000 nr_entries[i]++;
Namjae Jeon64b39f42021-03-30 14:25:35 +09001001 }
Namjae Jeone2f34482021-03-16 10:49:09 +09001002 total_entries += nr_entries[i];
1003 }
1004
1005 /* Add two entries for transform header and signature */
1006 total_entries += 2;
1007
1008 sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
1009 if (!sg)
1010 return NULL;
1011
1012 sg_init_table(sg, total_entries);
1013 smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1014 for (i = 0; i < nvec - 1; i++) {
1015 void *data = iov[i + 1].iov_base;
1016 int len = iov[i + 1].iov_len;
1017
1018 if (is_vmalloc_addr(data)) {
1019 int j, offset = offset_in_page(data);
1020
1021 for (j = 0; j < nr_entries[i]; j++) {
1022 unsigned int bytes = PAGE_SIZE - offset;
1023
Namjae Jeon08591cc2021-05-26 15:32:26 +09001024 if (!len)
Namjae Jeone2f34482021-03-16 10:49:09 +09001025 break;
1026
1027 if (bytes > len)
1028 bytes = len;
1029
1030 sg_set_page(&sg[sg_idx++],
1031 vmalloc_to_page(data), bytes,
1032 offset_in_page(data));
1033
1034 data += bytes;
1035 len -= bytes;
1036 offset = 0;
1037 }
1038 } else {
1039 sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1040 offset_in_page(data));
1041 }
Namjae Jeone2f34482021-03-16 10:49:09 +09001042 }
1043 smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1044 return sg;
1045}
1046
Namjae Jeon64b39f42021-03-30 14:25:35 +09001047int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
Namjae Jeon070fb212021-05-26 17:57:12 +09001048 unsigned int nvec, int enc)
Namjae Jeone2f34482021-03-16 10:49:09 +09001049{
1050 struct smb2_transform_hdr *tr_hdr =
1051 (struct smb2_transform_hdr *)iov[0].iov_base;
1052 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
Namjae Jeon03f1c3d2021-05-26 15:34:37 +09001053 int rc;
Namjae Jeone2f34482021-03-16 10:49:09 +09001054 struct scatterlist *sg;
1055 u8 sign[SMB2_SIGNATURE_SIZE] = {};
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001056 u8 key[SMB3_ENC_DEC_KEY_SIZE];
Namjae Jeone2f34482021-03-16 10:49:09 +09001057 struct aead_request *req;
1058 char *iv;
1059 unsigned int iv_len;
1060 struct crypto_aead *tfm;
1061 unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1062 struct ksmbd_crypto_ctx *ctx;
1063
1064 rc = ksmbd_get_encryption_key(conn,
1065 le64_to_cpu(tr_hdr->SessionId),
1066 enc,
1067 key);
1068 if (rc) {
Namjae Jeonbde16942021-06-28 15:23:19 +09001069 pr_err("Could not get %scryption key\n", enc ? "en" : "de");
Namjae Jeon27aa6462021-05-26 15:35:26 +09001070 return rc;
Namjae Jeone2f34482021-03-16 10:49:09 +09001071 }
1072
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001073 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1074 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
Namjae Jeone2f34482021-03-16 10:49:09 +09001075 ctx = ksmbd_crypto_ctx_find_gcm();
1076 else
1077 ctx = ksmbd_crypto_ctx_find_ccm();
1078 if (!ctx) {
Namjae Jeonbde16942021-06-28 15:23:19 +09001079 pr_err("crypto alloc failed\n");
Namjae Jeon0e579cd2021-05-26 16:34:56 +09001080 return -ENOMEM;
Namjae Jeone2f34482021-03-16 10:49:09 +09001081 }
1082
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001083 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1084 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
Namjae Jeone2f34482021-03-16 10:49:09 +09001085 tfm = CRYPTO_GCM(ctx);
1086 else
1087 tfm = CRYPTO_CCM(ctx);
1088
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001089 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1090 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1091 rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1092 else
1093 rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
Namjae Jeone2f34482021-03-16 10:49:09 +09001094 if (rc) {
Namjae Jeonbde16942021-06-28 15:23:19 +09001095 pr_err("Failed to set aead key %d\n", rc);
Namjae Jeone2f34482021-03-16 10:49:09 +09001096 goto free_ctx;
1097 }
1098
1099 rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1100 if (rc) {
Namjae Jeonbde16942021-06-28 15:23:19 +09001101 pr_err("Failed to set authsize %d\n", rc);
Namjae Jeone2f34482021-03-16 10:49:09 +09001102 goto free_ctx;
1103 }
1104
1105 req = aead_request_alloc(tfm, GFP_KERNEL);
1106 if (!req) {
Namjae Jeone2f34482021-03-16 10:49:09 +09001107 rc = -ENOMEM;
1108 goto free_ctx;
1109 }
1110
1111 if (!enc) {
1112 memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1113 crypt_len += SMB2_SIGNATURE_SIZE;
1114 }
1115
1116 sg = ksmbd_init_sg(iov, nvec, sign);
1117 if (!sg) {
Namjae Jeonbde16942021-06-28 15:23:19 +09001118 pr_err("Failed to init sg\n");
Namjae Jeone2f34482021-03-16 10:49:09 +09001119 rc = -ENOMEM;
1120 goto free_req;
1121 }
1122
1123 iv_len = crypto_aead_ivsize(tfm);
1124 iv = kzalloc(iv_len, GFP_KERNEL);
1125 if (!iv) {
Namjae Jeone2f34482021-03-16 10:49:09 +09001126 rc = -ENOMEM;
1127 goto free_sg;
1128 }
1129
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001130 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1131 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1132 memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
Namjae Jeon64b39f42021-03-30 14:25:35 +09001133 } else {
Namjae Jeone2f34482021-03-16 10:49:09 +09001134 iv[0] = 3;
Namjae Jeon5a0ca772021-05-06 11:43:37 +09001135 memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
Namjae Jeone2f34482021-03-16 10:49:09 +09001136 }
1137
1138 aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1139 aead_request_set_ad(req, assoc_data_len);
1140 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1141
1142 if (enc)
1143 rc = crypto_aead_encrypt(req);
1144 else
1145 rc = crypto_aead_decrypt(req);
Namjae Jeon73b8b082021-05-26 15:53:26 +09001146 if (rc)
1147 goto free_iv;
1148
1149 if (enc)
Namjae Jeone2f34482021-03-16 10:49:09 +09001150 memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1151
Namjae Jeon73b8b082021-05-26 15:53:26 +09001152free_iv:
Namjae Jeone2f34482021-03-16 10:49:09 +09001153 kfree(iv);
1154free_sg:
1155 kfree(sg);
1156free_req:
1157 kfree(req);
1158free_ctx:
1159 ksmbd_release_crypto_ctx(ctx);
1160 return rc;
1161}