|
29 | 29 | #include "mgmt/user_config.h"
|
30 | 30 | #include "crypto_ctx.h"
|
31 | 31 | #include "transport_ipc.h"
|
| 32 | +#include "../smbfs_common/arc4.h" |
32 | 33 |
|
33 | 34 | /*
|
34 | 35 | * Fixed format data defining GSS header and fixed string
|
@@ -336,6 +337,29 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
|
336 | 337 | nt_len - CIFS_ENCPWD_SIZE,
|
337 | 338 | domain_name, conn->ntlmssp.cryptkey);
|
338 | 339 | kfree(domain_name);
|
| 340 | + |
| 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 | + |
339 | 363 | return ret;
|
340 | 364 | }
|
341 | 365 |
|
@@ -408,6 +432,9 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
|
408 | 432 | (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
|
409 | 433 | flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
|
410 | 434 |
|
| 435 | + if (cflags & NTLMSSP_NEGOTIATE_KEY_XCH) |
| 436 | + flags |= NTLMSSP_NEGOTIATE_KEY_XCH; |
| 437 | + |
411 | 438 | chgblob->NegotiateFlags = cpu_to_le32(flags);
|
412 | 439 | len = strlen(ksmbd_netbios_name());
|
413 | 440 | name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
|
|
0 commit comments