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.
 
 
 
 
 
 

425 lines
8.4 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
block.c
Abstract:
Block encryption functions implementation :
RtlEncryptBlock
RtlDecryptBlock
RtlEncrypStdBlock
Author:
David Chalmers (Davidc) 10-21-91
Revision History:
Scott Field (sfield) 03-Nov-97
Removed critical section around crypto calls.
--*/
#include <nt.h>
#include <ntrtl.h>
#include <crypt.h>
#include <engine.h>
#include <nturtl.h>
#include <windows.h>
#include <ntddksec.h>
#ifndef KMODE
HANDLE g_hKsecDD = NULL;
VOID EncryptMemoryShutdown( VOID );
#endif
BOOLEAN
Sys003Initialize(
IN PVOID hmod,
IN ULONG Reason,
IN PCONTEXT Context
)
{
#ifndef KMODE
if( Reason == DLL_PROCESS_DETACH )
{
EncryptMemoryShutdown();
}
#endif
return TRUE;
DBG_UNREFERENCED_PARAMETER(hmod);
DBG_UNREFERENCED_PARAMETER(Context);
}
NTSTATUS
RtlEncryptBlock(
IN PCLEAR_BLOCK ClearBlock,
IN PBLOCK_KEY BlockKey,
OUT PCYPHER_BLOCK CypherBlock
)
/*++
Routine Description:
Takes a block of data and encrypts it with a key producing
an encrypted block of data.
Arguments:
ClearBlock - The block of data that is to be encrypted.
BlockKey - The key to use to encrypt data
CypherBlock - Encrypted data is returned here
Return Values:
STATUS_SUCCESS - The data was encrypted successfully. The encrypted
data block is in CypherBlock
STATUS_UNSUCCESSFUL - Something failed. The CypherBlock is undefined.
--*/
{
unsigned Result;
Result = DES_ECB_LM(ENCR_KEY,
(const char *)BlockKey,
(unsigned char *)ClearBlock,
(unsigned char *)CypherBlock
);
if (Result == CRYPT_OK) {
return(STATUS_SUCCESS);
} else {
#if DBG
DbgPrint("EncryptBlock failed\n\r");
#endif
return(STATUS_UNSUCCESSFUL);
}
}
NTSTATUS
RtlDecryptBlock(
IN PCYPHER_BLOCK CypherBlock,
IN PBLOCK_KEY BlockKey,
OUT PCLEAR_BLOCK ClearBlock
)
/*++
Routine Description:
Takes a block of encrypted data and decrypts it with a key producing
the clear block of data.
Arguments:
CypherBlock - The block of data to be decrypted
BlockKey - The key to use to decrypt data
ClearBlock - The decrpted block of data is returned here
Return Values:
STATUS_SUCCESS - The data was decrypted successfully. The decrypted
data block is in ClearBlock
STATUS_UNSUCCESSFUL - Something failed. The ClearBlock is undefined.
--*/
{
unsigned Result;
Result = DES_ECB_LM(DECR_KEY,
(const char *)BlockKey,
(unsigned char *)CypherBlock,
(unsigned char *)ClearBlock
);
if (Result == CRYPT_OK) {
return(STATUS_SUCCESS);
} else {
#if DBG
DbgPrint("DecryptBlock failed\n\r");
#endif
return(STATUS_UNSUCCESSFUL);
}
}
NTSTATUS
RtlEncryptStdBlock(
IN PBLOCK_KEY BlockKey,
OUT PCYPHER_BLOCK CypherBlock
)
/*++
Routine Description:
Takes a block key encrypts the standard text block with it.
The resulting encrypted block is returned.
This is a One-Way-Function - the key cannot be recovered from the
encrypted data block.
Arguments:
BlockKey - The key to use to encrypt the standard text block.
CypherBlock - The encrypted data is returned here
Return Values:
STATUS_SUCCESS - The encryption was successful.
The result is in CypherBlock
STATUS_UNSUCCESSFUL - Something failed. The CypherBlock is undefined.
--*/
{
unsigned Result;
char StdEncrPwd[] = "KGS!@#$%";
Result = DES_ECB_LM(ENCR_KEY,
(const char *)BlockKey,
(unsigned char *)StdEncrPwd,
(unsigned char *)CypherBlock
);
if (Result == CRYPT_OK) {
return(STATUS_SUCCESS);
} else {
#if DBG
DbgPrint("EncryptStd failed\n\r");
#endif
return(STATUS_UNSUCCESSFUL);
}
}
#ifndef KMODE
BOOLEAN
EncryptMemoryInitialize(
VOID
)
{
UNICODE_STRING DriverName;
OBJECT_ATTRIBUTES ObjA;
IO_STATUS_BLOCK IOSB;
HANDLE hFile;
NTSTATUS Status;
RtlInitUnicodeString( &DriverName, DD_KSEC_DEVICE_NAME_U );
InitializeObjectAttributes(
&ObjA,
&DriverName,
0,
NULL,
NULL
);
//
// needs to be non-alertable, else, the DeviceIoControl may return
// STATUS_USER_APC.
//
Status = NtOpenFile(
&hFile,
SYNCHRONIZE | FILE_READ_DATA,
&ObjA,
&IOSB,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_SYNCHRONOUS_IO_NONALERT
);
if(!NT_SUCCESS(Status))
{
return FALSE;
}
if(InterlockedCompareExchangePointer(
&g_hKsecDD,
hFile,
NULL
) != NULL)
{
NtClose( hFile );
}
return TRUE;
}
VOID
EncryptMemoryShutdown(
VOID
)
{
if( g_hKsecDD != NULL )
{
NtClose( g_hKsecDD );
g_hKsecDD = NULL;
}
}
NTSTATUS
RtlEncryptMemory(
IN PVOID Memory,
IN ULONG MemorySize,
IN ULONG OptionFlags
)
{
IO_STATUS_BLOCK IoStatus;
ULONG IoControlCode;
NTSTATUS Status;
if( g_hKsecDD == NULL )
{
if(!EncryptMemoryInitialize())
{
return STATUS_UNSUCCESSFUL;
}
}
switch( OptionFlags )
{
case 0:
{
IoControlCode = IOCTL_KSEC_ENCRYPT_MEMORY;
break;
}
case RTL_ENCRYPT_OPTION_CROSS_PROCESS:
{
IoControlCode = IOCTL_KSEC_ENCRYPT_MEMORY_CROSS_PROC;
break;
}
case RTL_ENCRYPT_OPTION_SAME_LOGON:
{
IoControlCode = IOCTL_KSEC_ENCRYPT_MEMORY_SAME_LOGON;
break;
}
default:
{
return STATUS_INVALID_PARAMETER;
}
}
Status = NtDeviceIoControlFile(
g_hKsecDD,
NULL,
NULL,
NULL,
&IoStatus,
IoControlCode,
Memory,
MemorySize, // output buffer size
Memory,
MemorySize
);
#if DBG
if((Status != 0) && (Status != STATUS_INVALID_PARAMETER))
{
KdPrint(("EncryptMemory IOCTL failed= 0x%lx\n\r", Status));
}
#endif
return Status;
}
NTSTATUS
RtlDecryptMemory(
IN PVOID Memory,
IN ULONG MemorySize,
IN ULONG OptionFlags
)
{
IO_STATUS_BLOCK IoStatus;
ULONG IoControlCode;
NTSTATUS Status;
if( g_hKsecDD == NULL )
{
if(!EncryptMemoryInitialize())
{
return STATUS_UNSUCCESSFUL;
}
}
switch( OptionFlags )
{
case 0:
{
IoControlCode = IOCTL_KSEC_DECRYPT_MEMORY;
break;
}
case RTL_ENCRYPT_OPTION_CROSS_PROCESS:
{
IoControlCode = IOCTL_KSEC_DECRYPT_MEMORY_CROSS_PROC;
break;
}
case RTL_ENCRYPT_OPTION_SAME_LOGON:
{
IoControlCode = IOCTL_KSEC_DECRYPT_MEMORY_SAME_LOGON;
break;
}
default:
{
return STATUS_INVALID_PARAMETER;
}
}
Status = NtDeviceIoControlFile(
g_hKsecDD,
NULL,
NULL,
NULL,
&IoStatus,
IoControlCode,
Memory,
MemorySize, // output buffer size
Memory,
MemorySize
);
#if DBG
if((Status != 0) && (Status != STATUS_INVALID_PARAMETER))
{
KdPrint(("DecryptMemory IOCTL failed= 0x%lx\n\r", Status));
}
#endif
return Status;
}
#endif