xref: /aosp_15_r20/external/cronet/net/ntlm/ntlm.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Based on [MS-NLMP]: NT LAN Manager (NTLM) Authentication Protocol
6 // Specification version 28.0 [1]. Additional NTLM reference [2].
7 //
8 // [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
9 // [2] http://davenport.sourceforge.net/ntlm.html
10 
11 #ifndef NET_NTLM_NTLM_H_
12 #define NET_NTLM_NTLM_H_
13 
14 #include <stddef.h>
15 #include <stdint.h>
16 
17 #include <memory>
18 #include <string>
19 #include <vector>
20 
21 #include "base/containers/span.h"
22 #include "base/strings/string_piece.h"
23 #include "net/base/net_export.h"
24 #include "net/ntlm/ntlm_constants.h"
25 
26 namespace net::ntlm {
27 
28 // Maps the bits in the NTLM Hash into 3 DES keys. The DES keys each have 56
29 // bits stored in the 7 most significant bits of 8 bytes. The least
30 // significant bit is undefined and will subsequently be set with odd parity
31 // prior to use.
32 NET_EXPORT_PRIVATE void Create3DesKeysFromNtlmHash(
33     base::span<const uint8_t, kNtlmHashLen> ntlm_hash,
34     base::span<uint8_t, 24> keys);
35 
36 // Generates the NTLMv1 Hash and writes the |kNtlmHashLen| byte result to
37 // |hash|. Defined by NTOWFv1() in [MS-NLMP] Section 3.3.1.
38 NET_EXPORT_PRIVATE void GenerateNtlmHashV1(
39     const std::u16string& password,
40     base::span<uint8_t, kNtlmHashLen> hash);
41 
42 // Generates the |kResponseLenV1| byte NTLMv1 response field according to the
43 // DESL(K, V) function in [MS-NLMP] Section 6.
44 NET_EXPORT_PRIVATE void GenerateResponseDesl(
45     base::span<const uint8_t, kNtlmHashLen> hash,
46     base::span<const uint8_t, kChallengeLen> challenge,
47     base::span<uint8_t, kResponseLenV1> response);
48 
49 // Generates the NTLM Response field for NTLMv1 without extended session
50 // security. Defined by ComputeResponse() in [MS-NLMP] Section 3.3.1 for the
51 // case where NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY is not set.
52 NET_EXPORT_PRIVATE void GenerateNtlmResponseV1(
53     const std::u16string& password,
54     base::span<const uint8_t, kChallengeLen> server_challenge,
55     base::span<uint8_t, kResponseLenV1> ntlm_response);
56 
57 // Generates both the LM Response and NTLM Response fields for NTLMv1 based
58 // on the users password and the servers challenge. Both the LM and NTLM
59 // Response are the result of |GenerateNtlmResponseV1|.
60 //
61 // NOTE: This should not be used. The default flags always include session
62 // security. Session security can however be disabled in NTLMv1 by omitting
63 // NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY from the flag set used to
64 // initialize |NtlmClient|.
65 //
66 // The default flags include this flag and the client will not be
67 // downgraded by the server.
68 NET_EXPORT_PRIVATE void GenerateResponsesV1(
69     const std::u16string& password,
70     base::span<const uint8_t, kChallengeLen> server_challenge,
71     base::span<uint8_t, kResponseLenV1> lm_response,
72     base::span<uint8_t, kResponseLenV1> ntlm_response);
73 
74 // The LM Response in V1 with extended session security is 8 bytes of the
75 // |client_challenge| then 16 bytes of zero. This is the value
76 // LmChallengeResponse in ComputeResponse() when
77 // NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY is set. See [MS-NLMP] Section
78 // 3.3.1.
79 NET_EXPORT_PRIVATE void GenerateLMResponseV1WithSessionSecurity(
80     base::span<const uint8_t, kChallengeLen> client_challenge,
81     base::span<uint8_t, kResponseLenV1> lm_response);
82 
83 // The |session_hash| is MD5(CONCAT(server_challenge, client_challenge)).
84 // It is used instead of just |server_challenge| in NTLMv1 when
85 // NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY is set. See [MS-NLMP] Section
86 // 3.3.1.
87 NET_EXPORT_PRIVATE void GenerateSessionHashV1WithSessionSecurity(
88     base::span<const uint8_t, kChallengeLen> server_challenge,
89     base::span<const uint8_t, kChallengeLen> client_challenge,
90     base::span<uint8_t, kNtlmHashLen> session_hash);
91 
92 // Generates the NTLM Response for NTLMv1 with session security.
93 // Defined by ComputeResponse() in [MS-NLMP] Section 3.3.1 for the
94 // case where NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY is set.
95 NET_EXPORT_PRIVATE void GenerateNtlmResponseV1WithSessionSecurity(
96     const std::u16string& password,
97     base::span<const uint8_t, kChallengeLen> server_challenge,
98     base::span<const uint8_t, kChallengeLen> client_challenge,
99     base::span<uint8_t, kResponseLenV1> ntlm_response);
100 
101 // Generates the responses for V1 with extended session security.
102 // This is also known as NTLM2 (which is not the same as NTLMv2).
103 // |lm_response| is the result of |GenerateLMResponseV1WithSessionSecurity| and
104 // |ntlm_response| is the result of |GenerateNtlmResponseV1WithSessionSecurity|.
105 // See [MS-NLMP] Section 3.3.1.
106 NET_EXPORT_PRIVATE void GenerateResponsesV1WithSessionSecurity(
107     const std::u16string& password,
108     base::span<const uint8_t, kChallengeLen> server_challenge,
109     base::span<const uint8_t, kChallengeLen> client_challenge,
110     base::span<uint8_t, kResponseLenV1> lm_response,
111     base::span<uint8_t, kResponseLenV1> ntlm_response);
112 
113 // Generates the NTLMv2 Hash and writes it into |v2_hash|.
114 NET_EXPORT_PRIVATE void GenerateNtlmHashV2(
115     const std::u16string& domain,
116     const std::u16string& username,
117     const std::u16string& password,
118     base::span<uint8_t, kNtlmHashLen> v2_hash);
119 
120 // In this implementation the Proof Input is the first 28 bytes of what
121 // [MS-NLMP] section 3.3.2 calls "temp". "temp" is part of the input to
122 // generate the NTLMv2 proof. "temp" is composed of a fixed 28 byte prefix
123 // (the Proof Input), then the variable length updated target info that is
124 // sent in the authenticate message, then followed by 4 zero bytes. See
125 // [MS-NLMP] Section 2.2.2.7.
126 //
127 // |timestamp| contains a 64 bit Windows timestamp defined as the number of
128 // 100 nanosecond ticks since midnight Jan 01, 1601 (UTC).
129 //
130 // The format of the returned |proof_input| is;
131 //
132 // [0-1]    - 0x0101                              (Version)
133 // [2-7]    - 0x000000000000                      (Reserved - all zero)
134 // [8-15]   - |timestamp|                         (Timestamp)
135 // [16-23]  - |client_challenge|                  (Client challenge)
136 // [24-27]  - 0x00000000                          (Reserved - all zero)
137 NET_EXPORT_PRIVATE std::vector<uint8_t> GenerateProofInputV2(
138     uint64_t timestamp,
139     base::span<const uint8_t, kChallengeLen> client_challenge);
140 
141 // The NTLMv2 Proof is part of the NTLMv2 Response. See NTProofStr in [MS-NLMP]
142 // Section 3.3.2.
143 //
144 // The NTLMv2 Proof is defined as;
145 //     v2_proof = HMAC_MD5(
146 //         v2_hash,
147 //         CONCAT(server_challenge, v2_input, target_info, 0x00000000))
148 NET_EXPORT_PRIVATE void GenerateNtlmProofV2(
149     base::span<const uint8_t, kNtlmHashLen> v2_hash,
150     base::span<const uint8_t, kChallengeLen> server_challenge,
151     base::span<const uint8_t, kProofInputLenV2> v2_input,
152     base::span<const uint8_t> target_info,
153     base::span<uint8_t, kNtlmProofLenV2> v2_proof);
154 
155 // The session base key is used to generate the Message Integrity Check (MIC).
156 // See [MS-NLMP] Section 3.3.2.
157 //
158 // It is defined as;
159 //     session_key = HMAC_MD5(v2_hash, v2_proof)
160 NET_EXPORT_PRIVATE void GenerateSessionBaseKeyV2(
161     base::span<const uint8_t, kNtlmHashLen> v2_hash,
162     base::span<const uint8_t, kNtlmProofLenV2> v2_proof,
163     base::span<uint8_t, kSessionKeyLenV2> session_key);
164 
165 // The channel bindings hash is an MD5 hash of a data structure containing
166 // a hash of the server's certificate.
167 //
168 // The |channel_bindings| string is supplied out of band (usually from a web
169 // browser) and is a (21+sizeof(hash)) byte ASCII string, where 'hash' is
170 // usually a SHA-256 of the servers certificate, but may be another hash
171 // algorithm. The format as defined by RFC 5929 Section 4 is shown below;
172 //
173 // [0-20]                 - "tls-server-end-point:"   (Literal string)
174 // [21-(20+sizeof(hash)]  - HASH(server_certificate)  (Certificate hash)
175 //
176 // The |channel_bindings| string is then combined into a data structure called
177 // gss_channel_bindings_struct (on Windows SEC_CHANNEL_BINDINGS) and MD5 hashed
178 // according to the rules in RFC 4121 Section 4.1.1.2. When simplified this
179 // results in the input to the hash (aka "ClientChannelBindingsUnhashed")
180 // being defined as follows;
181 //
182 // [0-15]   - 16 zero bytes                        (Collapsed fields)
183 // [16-19]  - |strlen(channel_bindings)|           (Length=0x00000035)
184 // [20-72]  - |channel_bindings|                   (Channel bindings)
185 //
186 // See also RFC 5056 and [MS-NLMP] Section 3.1.5.1.2.
187 //
188 // The channel bindings hash is then defined as;
189 //     channel_bindings_hash = MD5(ClientChannelBindingsUnhashed)
190 NET_EXPORT_PRIVATE void GenerateChannelBindingHashV2(
191     const std::string& channel_bindings,
192     base::span<uint8_t, kNtlmHashLen> channel_bindings_hash);
193 
194 // The Message Integrity Check (MIC) is a hash calculated over all three
195 // messages in the NTLM protocol. The MIC field in the authenticate message
196 // is set to all zeros when calculating the hash. See [MS-NLMP] Section
197 // 3.1.5.1.2.
198 //
199 // In this implementation NTLMSSP_NEGOTIATE_KEY_EXCH never negotiated and
200 // the MIC for this case is defined as below. If NTLMSSP_NEGOTIATE_KEY_EXCH
201 // was negotiated, an alternate key is used. See [MS-NLMP] SEction 3.1.5.1.2
202 // for additional details.
203 //
204 //     mic = HMAC_MD5(
205 //         session_base_key,
206 //         CONCAT(negotiate_msg, challenge_msg, authenticate_msg))
207 //
208 // |session_key| must contain |kSessionKeyLenV2| bytes.
209 // |mic| must contain |kMicLenV2| bytes.
210 NET_EXPORT_PRIVATE void GenerateMicV2(
211     base::span<const uint8_t, kSessionKeyLenV2> session_key,
212     base::span<const uint8_t> negotiate_msg,
213     base::span<const uint8_t> challenge_msg,
214     base::span<const uint8_t> authenticate_msg,
215     base::span<uint8_t, kMicLenV2> mic);
216 
217 // Updates the target info sent by the server, and generates the clients
218 // response target info.
219 NET_EXPORT_PRIVATE std::vector<uint8_t> GenerateUpdatedTargetInfo(
220     bool is_mic_enabled,
221     bool is_epa_enabled,
222     const std::string& channel_bindings,
223     const std::string& spn,
224     const std::vector<AvPair>& av_pairs,
225     uint64_t* server_timestamp);
226 
227 }  // namespace net::ntlm
228 
229 #endif  // NET_NTLM_NTLM_H_
230