20#include <winpr/config.h>
22#include <winpr/ntlm.h>
23#include <winpr/assert.h>
26#include <winpr/crypto.h>
34BOOL NTOWFv1W(LPCWSTR Password, UINT32 PasswordLengthInBytes, BYTE* NtHash)
36 if (!Password || !NtHash)
39 if (!winpr_Digest(WINPR_MD_MD4, Password, PasswordLengthInBytes, NtHash,
40 WINPR_MD4_DIGEST_LENGTH))
46BOOL NTOWFv1A(LPCSTR Password, UINT32 PasswordLengthInBytes, BYTE* NtHash)
48 LPWSTR PasswordW =
nullptr;
50 size_t pwdCharLength = 0;
55 if (!Password && (PasswordLengthInBytes > 0))
60 PasswordW = ConvertUtf8NToWCharAlloc(Password, PasswordLengthInBytes, &pwdCharLength);
65 if (!NTOWFv1W(PasswordW, WINPR_ASSERTING_INT_CAST(UINT32, pwdCharLength *
sizeof(WCHAR)),
82BOOL NTOWFv2W(LPCWSTR Password, UINT32 PasswordLengthInBytes, LPCWSTR User,
83 UINT32 UserLengthInBytes, LPCWSTR Domain, UINT32 DomainLengthInBytes, BYTE* NtHash)
85 BYTE NtHashV1[WINPR_MD5_DIGEST_LENGTH];
87 if (!Domain && (DomainLengthInBytes > 0))
89 if (!User || !Password || !NtHash)
92 if (!NTOWFv1W(Password, PasswordLengthInBytes, NtHashV1))
95 return NTOWFv2FromHashW(NtHashV1, User, UserLengthInBytes, Domain, DomainLengthInBytes, NtHash);
98BOOL NTOWFv2A(LPCSTR Password, UINT32 PasswordLengthInBytes, LPCSTR User, UINT32 UserLengthInBytes,
99 LPCSTR Domain, UINT32 DomainLengthInBytes, BYTE* NtHash)
101 LPWSTR UserW =
nullptr;
102 LPWSTR DomainW =
nullptr;
103 LPWSTR PasswordW =
nullptr;
105 size_t userCharLength = 0;
106 size_t domainCharLength = 0;
107 size_t pwdCharLength = 0;
112 if (!User && (UserLengthInBytes > 0))
114 if (!Password && (PasswordLengthInBytes > 0))
116 if (!Domain && (DomainLengthInBytes > 0))
121 UserW = ConvertUtf8NToWCharAlloc(User, UserLengthInBytes, &userCharLength);
127 DomainW = ConvertUtf8NToWCharAlloc(Domain, DomainLengthInBytes, &domainCharLength);
133 PasswordW = ConvertUtf8NToWCharAlloc(Password, PasswordLengthInBytes, &pwdCharLength);
138 if (!NTOWFv2W(PasswordW, (UINT32)pwdCharLength *
sizeof(WCHAR), UserW,
139 (UINT32)userCharLength *
sizeof(WCHAR), DomainW,
140 (UINT32)domainCharLength *
sizeof(WCHAR), NtHash))
151BOOL NTOWFv2FromHashW(
const BYTE* NtHashV1, LPCWSTR User, UINT32 UserLengthInBytes, LPCWSTR Domain,
152 UINT32 DomainLengthInBytes, BYTE* NtHash)
156 if (!NtHash || !NtHashV1)
159 if (!User && (UserLengthInBytes > 0))
161 if (!Domain && (DomainLengthInBytes > 0))
167 BYTE* buffer = (BYTE*)malloc(UserLengthInBytes + DomainLengthInBytes);
172 CopyMemory(buffer, User, UserLengthInBytes);
173 CharUpperBuffW((LPWSTR)buffer, UserLengthInBytes / 2);
175 if (DomainLengthInBytes > 0)
177 CopyMemory(&buffer[UserLengthInBytes], Domain, DomainLengthInBytes);
182 if (!winpr_HMAC(WINPR_MD_MD5, NtHashV1, 16, buffer, UserLengthInBytes + DomainLengthInBytes,
183 NtHash, WINPR_MD5_DIGEST_LENGTH))
192BOOL NTOWFv2FromHashA(
const BYTE* NtHashV1, LPCSTR User, UINT32 UserLengthInBytes, LPCSTR Domain,
193 UINT32 DomainLengthInBytes, BYTE* NtHash)
195 LPWSTR UserW =
nullptr;
196 LPWSTR DomainW =
nullptr;
198 size_t userCharLength = 0;
199 size_t domainCharLength = 0;
201 if (!NtHash || !NtHashV1)
204 if (!User && (UserLengthInBytes > 0))
206 if (!Domain && (DomainLengthInBytes > 0))
211 UserW = ConvertUtf8NToWCharAlloc(User, UserLengthInBytes, &userCharLength);
218 DomainW = ConvertUtf8NToWCharAlloc(Domain, DomainLengthInBytes, &domainCharLength);
223 if (!NTOWFv2FromHashW(NtHashV1, UserW, (UINT32)userCharLength *
sizeof(WCHAR), DomainW,
224 (UINT32)domainCharLength *
sizeof(WCHAR), NtHash))