windows-nt/Source/XPSP1/NT/ds/security/common/cryptdll/lmwrap.c

268 lines
5.2 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//
//
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#ifdef KERNEL_MODE
#include <ntos.h>
#endif
#include <security.h>
#include <cryptdll.h>
#include <crypt.h>
#include <kerbcon.h>
#include <lmcons.h>
#ifdef WIN32_CHICAGO
NTSTATUS
MyRtlUpcaseUnicodeStringToOemString(
OUT POEM_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
);
#define RtlUpcaseUnicodeStringToOemString(x, y, z) MyRtlUpcaseUnicodeStringToOemString(x, y, z)
#endif // WIN32_CHICAGO
typedef struct _LM_STATE_BUFFER {
LM_OWF_PASSWORD Password;
} LM_STATE_BUFFER, *PLM_STATE_BUFFER;
NTSTATUS
LmWrapInitialize(ULONG dwSeed,
PCHECKSUM_BUFFER * ppcsBuffer);
NTSTATUS
LmWrapSum( PCHECKSUM_BUFFER pcsBuffer,
ULONG cbData,
PUCHAR pbData );
NTSTATUS
LmWrapFinalize( PCHECKSUM_BUFFER pcsBuffer,
PUCHAR pbSum);
NTSTATUS
LmWrapFinish(PCHECKSUM_BUFFER * ppcsBuffer);
CHECKSUM_FUNCTION csfLM = {
KERB_CHECKSUM_LM,
LM_OWF_PASSWORD_LENGTH,
CKSUM_COLLISION,
LmWrapInitialize,
LmWrapSum,
LmWrapFinalize,
LmWrapFinish
// Note : missing last function
};
#ifdef KERNEL_MODE
#pragma alloc_text( PAGEMSG, LmWrapInitialize )
#pragma alloc_text( PAGEMSG, LmWrapSum )
#pragma alloc_text( PAGEMSG, LmWrapFinalize )
#pragma alloc_text( PAGEMSG, LmWrapFinish );
#endif
NTSTATUS
LmWrapInitialize(
ULONG dwSeed,
PCHECKSUM_BUFFER * ppcsBuffer)
{
PLM_STATE_BUFFER pContext;
#ifdef KERNEL_MODE
pContext = ExAllocatePool( NonPagedPool, sizeof( LM_STATE_BUFFER ) );
#else
pContext = LocalAlloc( LMEM_ZEROINIT, sizeof( LM_STATE_BUFFER ) );
#endif
if ( pContext != NULL )
{
*ppcsBuffer = pContext;
return( SEC_E_OK );
}
return( STATUS_INSUFFICIENT_RESOURCES );
}
NTSTATUS
LmCalculateLmPassword(
IN PUNICODE_STRING NtPassword,
OUT PCHAR *LmPasswordBuffer
)
/*++
Routine Description:
This service converts an NT password into a LM password.
Parameters:
NtPassword - The Nt password to be converted.
LmPasswordBuffer - On successful return, points at the LM password
The buffer should be freed using MIDL_user_free
Return Values:
STATUS_SUCCESS - LMPassword contains the LM version of the password.
STATUS_NULL_LM_PASSWORD - The password is too complex to be represented
by a LM password. The LM password returned is a NULL string.
--*/
{
#define LM_BUFFER_LENGTH (LM20_PWLEN + 1)
NTSTATUS NtStatus;
ANSI_STRING LmPassword;
//
// Prepare for failure
//
*LmPasswordBuffer = NULL;
//
// Compute the Ansi version to the Unicode password.
//
// The Ansi version of the Cleartext password is at most 14 bytes long,
// exists in a trailing zero filled 15 byte buffer,
// is uppercased.
//
#ifdef KERNEL_MODE
LmPassword.Buffer = ExAllocatePool(NonPagedPool,LM_BUFFER_LENGTH);
#else
LmPassword.Buffer = LocalAlloc(0,LM_BUFFER_LENGTH);
#endif
if (LmPassword.Buffer == NULL) {
return(STATUS_INSUFFICIENT_RESOURCES);
}
LmPassword.MaximumLength = LmPassword.Length = LM_BUFFER_LENGTH;
RtlZeroMemory( LmPassword.Buffer, LM_BUFFER_LENGTH );
NtStatus = RtlUpcaseUnicodeStringToOemString( &LmPassword, NtPassword, FALSE );
if ( !NT_SUCCESS(NtStatus) ) {
//
// The password is longer than the max LM password length
//
NtStatus = STATUS_NULL_LM_PASSWORD; // Informational return code
RtlZeroMemory( LmPassword.Buffer, LM_BUFFER_LENGTH );
}
//
// Return a pointer to the allocated LM password
//
if (NT_SUCCESS(NtStatus)) {
*LmPasswordBuffer = LmPassword.Buffer;
} else {
#ifdef KERNEL_MODE
ExFreePool(LmPassword.Buffer);
#else
LocalFree(LmPassword.Buffer);
#endif
}
return(NtStatus);
}
NTSTATUS
LmWrapSum(
PCHECKSUM_BUFFER pcsBuffer,
ULONG cbData,
PUCHAR pbData )
{
PLM_STATE_BUFFER pContext = (PLM_STATE_BUFFER) pcsBuffer;
UNICODE_STRING TempString;
PUCHAR LmPassword;
NTSTATUS Status;
TempString.Length = TempString.MaximumLength = (USHORT) cbData;
TempString.Buffer = (LPWSTR) pbData;
Status = LmCalculateLmPassword(
&TempString,
&LmPassword
);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Status = RtlCalculateLmOwfPassword(
LmPassword,
&pContext->Password
);
#ifdef KERNEL_MODE
ExFreePool(LmPassword);
#else
LocalFree(LmPassword);
#endif
return( Status );
}
NTSTATUS
LmWrapFinalize(
PCHECKSUM_BUFFER pcsBuffer,
PUCHAR pbSum)
{
PLM_STATE_BUFFER pContext = (PLM_STATE_BUFFER) pcsBuffer;
RtlCopyMemory(
pbSum,
&pContext->Password,
LM_OWF_PASSWORD_LENGTH
);
return( STATUS_SUCCESS );
}
NTSTATUS
LmWrapFinish(
PCHECKSUM_BUFFER * ppcsBuffer)
{
RtlZeroMemory( *ppcsBuffer, sizeof( PLM_STATE_BUFFER ) );
#ifdef KERNEL_MODE
ExFreePool( *ppcsBuffer );
#else
LocalFree( *ppcsBuffer );
#endif
*ppcsBuffer = NULL ;
return( STATUS_SUCCESS );
}