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