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