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.

155 lines
3.3 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. response.c
  5. Abstract:
  6. Contains functions that calculate the correct response to return
  7. to the server when logging on.
  8. RtlCalculateLmResponse
  9. RtlCalculateNtResponse
  10. Author:
  11. David Chalmers (Davidc) 10-21-91
  12. Revision History:
  13. --*/
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <crypt.h>
  17. NTSTATUS
  18. RtlCalculateLmResponse(
  19. IN PLM_CHALLENGE LmChallenge,
  20. IN PLM_OWF_PASSWORD LmOwfPassword,
  21. OUT PLM_RESPONSE LmResponse
  22. )
  23. /*++
  24. Routine Description:
  25. Takes the challenge sent by the server and the OwfPassword generated
  26. from the password the user entered and calculates the response to
  27. return to the server.
  28. Arguments:
  29. LmChallenge - The challenge sent by the server
  30. LmOwfPassword - The hashed password.
  31. LmResponse - The response is returned here.
  32. Return Values:
  33. STATUS_SUCCESS - The function completed successfully. The response
  34. is in LmResponse.
  35. STATUS_UNSUCCESSFUL - Something failed. The LmResponse is undefined.
  36. --*/
  37. {
  38. NTSTATUS Status;
  39. BLOCK_KEY Key;
  40. PCHAR pKey, pData;
  41. // The first 2 keys we can get at by type-casting
  42. Status = RtlEncryptBlock(LmChallenge,
  43. &(((PBLOCK_KEY)(LmOwfPassword->data))[0]),
  44. &(LmResponse->data[0]));
  45. if (!NT_SUCCESS(Status)) {
  46. return(Status);
  47. }
  48. Status = RtlEncryptBlock(LmChallenge,
  49. &(((PBLOCK_KEY)(LmOwfPassword->data))[1]),
  50. &(LmResponse->data[1]));
  51. if (!NT_SUCCESS(Status)) {
  52. return(Status);
  53. }
  54. // To get the last key we must copy the remainder of the OwfPassword
  55. // and fill the rest of the key with 0s
  56. pKey = &(Key.data[0]);
  57. pData = (PCHAR)&(((PBLOCK_KEY)(LmOwfPassword->data))[2]);
  58. while (pData < (PCHAR)&(LmOwfPassword->data[2])) {
  59. *pKey++ = *pData++;
  60. }
  61. // Zero extend
  62. while (pKey < (PCHAR)&((&Key)[1])) {
  63. *pKey++ = 0;
  64. }
  65. // Use the 3rd key
  66. Status = RtlEncryptBlock(LmChallenge, &Key, &(LmResponse->data[2]));
  67. RtlSecureZeroMemory( &Key, sizeof(Key) );
  68. return(Status);
  69. }
  70. NTSTATUS
  71. RtlCalculateNtResponse(
  72. IN PNT_CHALLENGE NtChallenge,
  73. IN PNT_OWF_PASSWORD NtOwfPassword,
  74. OUT PNT_RESPONSE NtResponse
  75. )
  76. /*++
  77. Routine Description:
  78. Takes the challenge sent by the server and the OwfPassword generated
  79. from the password the user entered and calculates the response to
  80. return(to the server.
  81. Arguments:
  82. NtChallenge - The challenge sent by the server
  83. NtOwfPassword - The hashed password.
  84. NtResponse - The response is returned here.
  85. Return Values:
  86. STATUS_SUCCESS - The function completed successfully. The response
  87. is in NtResponse.
  88. STATUS_UNSUCCESSFUL - Something failed. The NtResponse is undefined.
  89. --*/
  90. {
  91. // Use the LM version until we change the definitions of any of
  92. // these data types
  93. return(RtlCalculateLmResponse((PLM_CHALLENGE)NtChallenge,
  94. (PLM_OWF_PASSWORD)NtOwfPassword,
  95. (PLM_RESPONSE)NtResponse));
  96. }