/*++ Copyright (c) 1989-1997 Microsoft Corporation Module Name: userkey.c Abstract: Implentation of the functions that get and generate user session keys RtlCalculateUserSessionKeyLm RtlCalculateUserSessionKeyNt Author: David Chalmers (Davidc) 10-21-91 Revision History: Adam Barr (AdamBa) 12-15-97 Modified from private\security\lsa\crypt\dll --*/ #include // // Define this if you want to know all about user session keys // // #define DEBUG_USER_SESSION_KEYS // // Define the user session key that represents an error. // This value will be generated by other parts of the system on failure. // We will check for it in our query code and return an error if it's found. // USER_SESSION_KEY ErrorSessionKey = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; NTSTATUS RtlCalculateUserSessionKeyLm( IN PLM_RESPONSE LmResponse, IN PLM_OWF_PASSWORD LmOwfPassword, OUT PUSER_SESSION_KEY UserSessionKey) /*++ Routine Description: Takes the passed Response and OwfPassword and generates a UserSessionKey. The current implementation takes the one-way-function of the OwfPassword and returns this as the key. Arguments: LmResponse - The response sent during session setup. LmOwfPassword - The hashed version of the user's password. Return Values: STATUS_SUCCESS - The function was completed successfully. The UserSessionKey is in UserSessionKey. STATUS_UNSUCCESSFUL - Something failed. The UserSessionKey is undefined. --*/ { NTSTATUS Status; NT_PASSWORD NtPassword; // // Make the Owf password look like an NT password // NtPassword.Buffer = (PWSTR)LmOwfPassword; // We can do this cast because we // know the OWF routine treats this // pointer as a byte pointer. NtPassword.Length = sizeof(*LmOwfPassword); NtPassword.MaximumLength = sizeof(*LmOwfPassword); // // Calculate the OWF of the OwfPassword // ASSERT(sizeof(NT_OWF_PASSWORD) == sizeof(*UserSessionKey)); Status = RtlCalculateNtOwfPassword( &NtPassword, (PNT_OWF_PASSWORD)UserSessionKey ); if (!NT_SUCCESS(Status)) { KdPrint(("RtlCalculateUserSessionKeyLm : OWF calculation failed, status = 0x%lx\n", Status)); return(Status); } // // Check if we've generated the error session key // if (RtlCompareMemory(UserSessionKey, &ErrorSessionKey, sizeof(*UserSessionKey)) == sizeof(*UserSessionKey)) { #ifdef DEBUG_USER_SESSION_KEYS KdPrint(("RtlCalculateSessionKeyLm - generated error session key, modifying it\n")); #endif // // Move away from the error session key // UserSessionKey->data[0].data[0] ++; ASSERT(RtlCompareMemory(UserSessionKey, &ErrorSessionKey, sizeof(*UserSessionKey)) != sizeof(*UserSessionKey)); } #ifdef DEBUG_USER_SESSION_KEYS KdPrint(("RtlCalculateUserSessionKeyLm : Key = 0x%lx : %lx : %lx : %lx\n", ((PULONG)UserSessionKey)[0], ((PULONG)UserSessionKey)[1], ((PULONG)UserSessionKey)[2], ((PULONG)UserSessionKey)[3])); #endif return(STATUS_SUCCESS); UNREFERENCED_PARAMETER(LmResponse); } NTSTATUS RtlCalculateUserSessionKeyNt( IN PNT_RESPONSE NtResponse, IN PNT_OWF_PASSWORD NtOwfPassword, OUT PUSER_SESSION_KEY UserSessionKey) /*++ Routine Description: Takes the passed Response and OwfPassword and generates a UserSessionKey. Arguments: NtResponse - The response sent during session setup. NtOwfPassword - The hashed version of the user's password. Return Values: STATUS_SUCCESS - The function was completed successfully. The UserSessionKey is in UserSessionKey. STATUS_UNSUCCESSFUL - Something failed. The UserSessionKey is undefined. --*/ { // Just call the LM version ASSERT(sizeof(NT_RESPONSE) == sizeof(LM_RESPONSE)); ASSERT(sizeof(NT_OWF_PASSWORD) == sizeof(LM_OWF_PASSWORD)); return(RtlCalculateUserSessionKeyLm((PLM_RESPONSE)NtResponse, (PLM_OWF_PASSWORD)NtOwfPassword, UserSessionKey)); }