Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: net/ntlm/ntlm.cc

Issue 2873673002: Add unit tests for NTLMv1 portable implementation (Closed)
Patch Set: Rebase Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/ntlm/ntlm.h ('k') | net/ntlm/ntlm_constants.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/ntlm/ntlm.h"
6
7 #include <string.h>
8
9 #include "base/logging.h"
10 #include "base/md5.h"
11 #include "net/ntlm/des.h"
12 #include "net/ntlm/md4.h"
13 #include "net/ntlm/ntlm_buffer_writer.h"
14
15 namespace net {
16 namespace ntlm {
17
18 void GenerateNtlmHashV1(const base::string16& password, uint8_t* hash) {
19 size_t length = password.length() * 2;
20 NtlmBufferWriter writer(length);
21
22 // The writer will handle the big endian case if necessary.
23 bool result = writer.WriteUtf16String(password);
24 DCHECK(result);
25
26 weak_crypto::MD4Sum(
27 reinterpret_cast<const uint8_t*>(writer.GetBuffer().data()), length,
28 hash);
29 }
30
31 void GenerateResponseDesl(const uint8_t* hash,
32 const uint8_t* challenge,
33 uint8_t* response) {
34 // See DESL(K, D) function in [MS-NLMP] Section 6
35 uint8_t key1[8];
36 uint8_t key2[8];
37 uint8_t key3[8];
38
39 // The last 2 bytes of the hash are zero padded (5 zeros) as the
40 // input to generate key3.
41 uint8_t padded_hash[7];
42 padded_hash[0] = hash[14];
43 padded_hash[1] = hash[15];
44 memset(padded_hash + 2, 0, 5);
45
46 DESMakeKey(hash, key1);
47 DESMakeKey(hash + 7, key2);
48 DESMakeKey(padded_hash, key3);
49
50 DESEncrypt(key1, challenge, response);
51 DESEncrypt(key2, challenge, response + 8);
52 DESEncrypt(key3, challenge, response + 16);
53 }
54
55 void GenerateNtlmResponseV1(const base::string16& password,
56 const uint8_t* challenge,
57 uint8_t* ntlm_response) {
58 uint8_t ntlm_hash[kNtlmHashLen];
59 GenerateNtlmHashV1(password, ntlm_hash);
60 GenerateResponseDesl(ntlm_hash, challenge, ntlm_response);
61 }
62
63 void GenerateResponsesV1(const base::string16& password,
64 const uint8_t* server_challenge,
65 uint8_t* lm_response,
66 uint8_t* ntlm_response) {
67 GenerateNtlmResponseV1(password, server_challenge, ntlm_response);
68
69 // In NTLM v1 (with LMv1 disabled), the lm_response and ntlm_response are the
70 // same. So just copy the ntlm_response into the lm_response.
71 memcpy(lm_response, ntlm_response, kResponseLenV1);
72 }
73
74 void GenerateLMResponseV1WithSessionSecurity(const uint8_t* client_challenge,
75 uint8_t* lm_response) {
76 // In NTLM v1 with Session Security (aka NTLM2) the lm_response is 8 bytes of
77 // client challenge and 16 bytes of zeros. (See 3.3.1)
78 memcpy(lm_response, client_challenge, kChallengeLen);
79 memset(lm_response + kChallengeLen, 0, kResponseLenV1 - kChallengeLen);
80 }
81
82 void GenerateSessionHashV1WithSessionSecurity(const uint8_t* server_challenge,
83 const uint8_t* client_challenge,
84 base::MD5Digest* session_hash) {
85 base::MD5Context ctx;
86 base::MD5Init(&ctx);
87 base::MD5Update(
88 &ctx, base::StringPiece(reinterpret_cast<const char*>(server_challenge),
89 kChallengeLen));
90 base::MD5Update(
91 &ctx, base::StringPiece(reinterpret_cast<const char*>(client_challenge),
92 kChallengeLen));
93
94 base::MD5Final(session_hash, &ctx);
95 }
96
97 void GenerateNtlmResponseV1WithSessionSecurity(const base::string16& password,
98 const uint8_t* server_challenge,
99 const uint8_t* client_challenge,
100 uint8_t* ntlm_response) {
101 // Generate the NTLMv1 Hash.
102 uint8_t ntlm_hash[kNtlmHashLen];
103 GenerateNtlmHashV1(password, ntlm_hash);
104
105 // Generate the NTLMv1 Session Hash.
106 base::MD5Digest session_hash;
107 GenerateSessionHashV1WithSessionSecurity(server_challenge, client_challenge,
108 &session_hash);
109
110 // Only the first 8 bytes of |session_hash.a| are actually used.
111 GenerateResponseDesl(ntlm_hash, session_hash.a, ntlm_response);
112 }
113
114 void GenerateResponsesV1WithSessionSecurity(const base::string16& password,
115 const uint8_t* server_challenge,
116 const uint8_t* client_challenge,
117 uint8_t* lm_response,
118 uint8_t* ntlm_response) {
119 GenerateLMResponseV1WithSessionSecurity(client_challenge, lm_response);
120 GenerateNtlmResponseV1WithSessionSecurity(password, server_challenge,
121 client_challenge, ntlm_response);
122 }
123
124 } // namespace ntlm
125 } // namespace net
OLDNEW
« no previous file with comments | « net/ntlm/ntlm.h ('k') | net/ntlm/ntlm_constants.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698