Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
4.6 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. owf.c
  5. Abstract:
  6. Implentation of the one-way-functions used to implement password hashing.
  7. CalculateLmOwfPassword
  8. CalculateNtOwfPassword
  9. Author:
  10. David Chalmers (Davidc) 10-21-91
  11. David Arnold (DavidAr) 12-15-93 (Adapted for WfW RPC SSP)
  12. Revision History:
  13. --*/
  14. #include <windows.h>
  15. #include <descrypt.h>
  16. #include <md4.h>
  17. #include "encrypt.h"
  18. BOOL
  19. CalculateLmOwfPassword(
  20. IN PLM_PASSWORD LmPassword,
  21. OUT PLM_OWF_PASSWORD LmOwfPassword
  22. )
  23. /*++
  24. Routine Description:
  25. Takes the passed LmPassword and performs a one-way-function on it.
  26. The current implementation does this by using the password as a key
  27. to encrypt a known block of text.
  28. Arguments:
  29. LmPassword - The password to perform the one-way-function on.
  30. LmOwfPassword - The hashed password is returned here
  31. Return Values:
  32. TRUE - The function was completed successfully. The hashed
  33. password is in LmOwfPassword.
  34. FALSE - Something failed. The LmOwfPassword is undefined.
  35. --*/
  36. {
  37. char StdEncrPwd[] = "KGS!@#$%";
  38. BLOCK_KEY Key[2];
  39. PCHAR pKey;
  40. // Copy the password into our key buffer and zero pad to fill the 2 keys
  41. pKey = (PCHAR)(&Key[0]);
  42. while (*LmPassword && (pKey < (PCHAR)(&Key[2]))) {
  43. *pKey++ = *LmPassword++;
  44. }
  45. while (pKey < (PCHAR)(&Key[2])) {
  46. *pKey++ = 0;
  47. }
  48. // Use the keys to encrypt the standard text
  49. if (DES_ECB_LM(ENCR_KEY,
  50. (unsigned char *)&Key[0],
  51. (unsigned char *)StdEncrPwd,
  52. (unsigned char *)&LmOwfPassword->data[0]
  53. ) != CRYPT_OK) {
  54. return (FALSE);
  55. }
  56. if (DES_ECB_LM(ENCR_KEY,
  57. (unsigned char *)&Key[1],
  58. (unsigned char *)StdEncrPwd,
  59. (unsigned char *)&LmOwfPassword->data[1]
  60. ) != CRYPT_OK) {
  61. return (FALSE);
  62. }
  63. //
  64. // clear our copy of the cleartext password
  65. //
  66. pKey = (PCHAR)(&Key[0]);
  67. while (pKey < (PCHAR)(&Key[2])) {
  68. *pKey++ = 0;
  69. }
  70. return(TRUE);
  71. }
  72. BOOL
  73. CalculateNtOwfPassword(
  74. IN PNT_PASSWORD NtPassword,
  75. OUT PNT_OWF_PASSWORD NtOwfPassword
  76. )
  77. /*++
  78. Routine Description:
  79. Takes the passed NtPassword and performs a one-way-function on it.
  80. Uses the RSA MD4 function
  81. Arguments:
  82. NtPassword - The password to perform the one-way-function on.
  83. NtOwfPassword - The hashed password is returned here
  84. Return Values:
  85. TRUE - The function was completed successfully. The hashed
  86. password is in NtOwfPassword.
  87. --*/
  88. {
  89. MD4_CTX MD4_Context;
  90. MD4Init(&MD4_Context);
  91. MD4Update(&MD4_Context, (PCHAR)NtPassword->Buffer, NtPassword->Length);
  92. MD4Final(&MD4_Context);
  93. if (sizeof(*NtOwfPassword) != sizeof(MD4_Context.digest)) {
  94. return(FALSE);
  95. }
  96. memcpy((PVOID)NtOwfPassword, (PVOID)MD4_Context.digest, sizeof(*NtOwfPassword));
  97. return(TRUE);
  98. }
  99. INT
  100. CompareLmPasswords (
  101. IN PLM_OWF_PASSWORD LmOwfPassword1,
  102. IN PLM_OWF_PASSWORD LmOwfPassword2
  103. )
  104. /*++
  105. Routine Description:
  106. Compares 2 LM OWF passwords.
  107. Arguments:
  108. LmOwfPassword1 - The first password to compare
  109. LmOwfPassword2 - The second password to compare
  110. Return Values:
  111. 0 if they are equal, -1 if first is smaller (regarded as a string of bytes),
  112. 1 if first is greater
  113. --*/
  114. {
  115. PBYTE p1 = (PBYTE)LmOwfPassword1;
  116. PBYTE p2 = (PBYTE)LmOwfPassword2;
  117. DWORD size = sizeof (LM_OWF_PASSWORD);
  118. CHAR diff;
  119. while (size--) {
  120. diff = *p1++ - *p2++;
  121. if (diff) {
  122. return (INT)diff;
  123. }
  124. }
  125. return 0;
  126. }
  127. INT
  128. CompareNtPasswords (
  129. IN PNT_OWF_PASSWORD NtOwfPassword1,
  130. IN PNT_OWF_PASSWORD NtOwfPassword2
  131. )
  132. /*++
  133. Routine Description:
  134. Compares 2 NT OWF passwords.
  135. Arguments:
  136. NtOwfPassword1 - The first password to compare
  137. NtOwfPassword2 - The second password to compare
  138. Return Values:
  139. 0 if they are equal, -1 if first is smaller (regarded as a string of bytes),
  140. 1 if first is greater
  141. --*/
  142. {
  143. PBYTE p1 = (PBYTE)NtOwfPassword1;
  144. PBYTE p2 = (PBYTE)NtOwfPassword2;
  145. DWORD size = sizeof (NT_OWF_PASSWORD);
  146. CHAR diff;
  147. while (size--) {
  148. diff = *p1++ - *p2++;
  149. if (diff) {
  150. return (INT)diff;
  151. }
  152. }
  153. return 0;
  154. }