392 lines
9.7 KiB
C
392 lines
9.7 KiB
C
|
//+-----------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation 1999
|
||
|
//
|
||
|
// File: fipscryp.c
|
||
|
//
|
||
|
// Contents: Base level stuff for the FIPS mode crypto device driver
|
||
|
//
|
||
|
//
|
||
|
// History: 04 JAN 00, Jeffspel Stolen from KSECDD
|
||
|
// FEB 00, kschutz
|
||
|
//
|
||
|
//------------------------------------------------------------------------
|
||
|
|
||
|
#include <ntddk.h>
|
||
|
#include <fipsapi.h>
|
||
|
#include <fipslog.h>
|
||
|
#include <randlib.h>
|
||
|
|
||
|
#pragma hdrstop
|
||
|
|
||
|
NTSTATUS SelfMACCheck(IN LPWSTR pszImage);
|
||
|
NTSTATUS AlgorithmCheck(void);
|
||
|
|
||
|
|
||
|
/*
|
||
|
typedef struct _DEVICE_EXTENSION {
|
||
|
|
||
|
ULONG OpenCount;
|
||
|
PVOID CodeHandle;
|
||
|
PVOID DataHandle;
|
||
|
|
||
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||
|
*/
|
||
|
|
||
|
VOID
|
||
|
FipsLogError(
|
||
|
IN PVOID Object,
|
||
|
IN NTSTATUS ErrorCode,
|
||
|
IN PUNICODE_STRING Insertion,
|
||
|
IN ULONG DumpData
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine allocates an error log entry, copies the supplied data
|
||
|
to it, and requests that it be written to the error log file.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
DeviceObject - Supplies a pointer to the device object associated
|
||
|
with the device that had the error, early in
|
||
|
initialization, one may not yet exist.
|
||
|
|
||
|
Insertion - An insertion string that can be used to log
|
||
|
additional data. Note that the message file
|
||
|
needs %2 for this insertion, since %1
|
||
|
is the name of the driver
|
||
|
|
||
|
ErrorCode - Supplies the IO status for this particular error.
|
||
|
|
||
|
DumpData - One word to dump
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
PIO_ERROR_LOG_PACKET errorLogEntry;
|
||
|
|
||
|
errorLogEntry = IoAllocateErrorLogEntry(
|
||
|
Object,
|
||
|
(UCHAR) (
|
||
|
sizeof(IO_ERROR_LOG_PACKET) +
|
||
|
(Insertion ? Insertion->Length + sizeof(WCHAR) : 0)
|
||
|
)
|
||
|
);
|
||
|
|
||
|
ASSERT(errorLogEntry != NULL);
|
||
|
|
||
|
if (errorLogEntry == NULL) {
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
errorLogEntry->ErrorCode = ErrorCode;
|
||
|
errorLogEntry->SequenceNumber = 0;
|
||
|
errorLogEntry->MajorFunctionCode = 0;
|
||
|
errorLogEntry->RetryCount = 0;
|
||
|
errorLogEntry->UniqueErrorValue = 0;
|
||
|
errorLogEntry->FinalStatus = STATUS_SUCCESS;
|
||
|
errorLogEntry->DumpDataSize = (DumpData ? sizeof(ULONG) : 0);
|
||
|
errorLogEntry->DumpData[0] = DumpData;
|
||
|
|
||
|
if (Insertion) {
|
||
|
|
||
|
errorLogEntry->StringOffset =
|
||
|
sizeof(IO_ERROR_LOG_PACKET);
|
||
|
|
||
|
errorLogEntry->NumberOfStrings = 1;
|
||
|
|
||
|
RtlCopyMemory(
|
||
|
((PCHAR)(errorLogEntry) + errorLogEntry->StringOffset),
|
||
|
Insertion->Buffer,
|
||
|
Insertion->Length
|
||
|
);
|
||
|
}
|
||
|
|
||
|
IoWriteErrorLogEntry(errorLogEntry);
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
FipsCreateClose(
|
||
|
IN PDEVICE_OBJECT DeviceObject,
|
||
|
IN PIRP Irp
|
||
|
)
|
||
|
{
|
||
|
//PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
|
||
|
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
||
|
|
||
|
/*
|
||
|
if (irpStack->MajorFunction == IRP_MJ_CREATE) {
|
||
|
|
||
|
if (deviceExtension->OpenCount++ == 0) {
|
||
|
|
||
|
extern DWORD Spbox[8][64];
|
||
|
|
||
|
deviceExtension->CodeHandle = MmLockPagableCodeSection(A_SHAInit);
|
||
|
MmLockPagableSectionByHandle(deviceExtension->CodeHandle);
|
||
|
|
||
|
deviceExtension->DataHandle = MmLockPagableDataSection(Spbox);
|
||
|
MmLockPagableSectionByHandle(deviceExtension->DataHandle);
|
||
|
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
if (--deviceExtension->OpenCount == 0) {
|
||
|
|
||
|
MmUnlockPagableImageSection(deviceExtension->CodeHandle);
|
||
|
MmUnlockPagableImageSection(deviceExtension->DataHandle);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
Irp->IoStatus.Information = 0;
|
||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||
|
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
FipsDeviceControl(
|
||
|
IN PDEVICE_OBJECT DeviceObject,
|
||
|
IN PIRP Irp
|
||
|
)
|
||
|
{
|
||
|
PIO_STACK_LOCATION ioStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||
|
ULONG ioControlCode = ioStackLocation->Parameters.DeviceIoControl.IoControlCode;
|
||
|
NTSTATUS status = STATUS_NOT_SUPPORTED;
|
||
|
|
||
|
Irp->IoStatus.Information = 0;
|
||
|
|
||
|
switch (ioControlCode) {
|
||
|
|
||
|
FIPS_FUNCTION_TABLE FipsFuncs;
|
||
|
FIPS_FUNCTION_TABLE_1 OldFipsFuncsV1;
|
||
|
|
||
|
case IOCTL_FIPS_GET_FUNCTION_TABLE:
|
||
|
|
||
|
if (ioStackLocation->Parameters.DeviceIoControl.OutputBufferLength >=
|
||
|
sizeof(FipsFuncs)) {
|
||
|
|
||
|
FipsFuncs.FipsDesKey = FipsDesKey;
|
||
|
FipsFuncs.FipsDes = FipsDes;
|
||
|
FipsFuncs.Fips3Des3Key = Fips3Des3Key;
|
||
|
FipsFuncs.Fips3Des = Fips3Des;
|
||
|
FipsFuncs.FipsSHAInit = FipsSHAInit;
|
||
|
FipsFuncs.FipsSHAUpdate = FipsSHAUpdate;
|
||
|
FipsFuncs.FipsSHAFinal = FipsSHAFinal;
|
||
|
FipsFuncs.FipsCBC = FipsCBC;
|
||
|
FipsFuncs.FIPSGenRandom = FIPSGenRandom;
|
||
|
FipsFuncs.FipsBlockCBC = FipsBlockCBC;
|
||
|
FipsFuncs.FipsHmacSHAInit = FipsHmacSHAInit;
|
||
|
FipsFuncs.FipsHmacSHAUpdate = FipsHmacSHAUpdate;
|
||
|
FipsFuncs.FipsHmacSHAFinal = FipsHmacSHAFinal;
|
||
|
FipsFuncs.HmacMD5Init = HmacMD5Init;
|
||
|
FipsFuncs.HmacMD5Update = HmacMD5Update;
|
||
|
FipsFuncs.HmacMD5Final = HmacMD5Final;
|
||
|
|
||
|
*((PFIPS_FUNCTION_TABLE) Irp->AssociatedIrp.SystemBuffer) =
|
||
|
FipsFuncs;
|
||
|
|
||
|
Irp->IoStatus.Information = sizeof(FipsFuncs);
|
||
|
|
||
|
status = STATUS_SUCCESS;
|
||
|
|
||
|
} else if (ioStackLocation->Parameters.DeviceIoControl.OutputBufferLength >=
|
||
|
sizeof(OldFipsFuncsV1)) {
|
||
|
|
||
|
OldFipsFuncsV1.FipsDesKey = FipsDesKey;
|
||
|
OldFipsFuncsV1.FipsDes = FipsDes;
|
||
|
OldFipsFuncsV1.Fips3Des3Key = Fips3Des3Key;
|
||
|
OldFipsFuncsV1.Fips3Des = Fips3Des;
|
||
|
OldFipsFuncsV1.FipsSHAInit = FipsSHAInit;
|
||
|
OldFipsFuncsV1.FipsSHAUpdate = FipsSHAUpdate;
|
||
|
OldFipsFuncsV1.FipsSHAFinal = FipsSHAFinal;
|
||
|
OldFipsFuncsV1.FipsCBC = FipsCBC;
|
||
|
OldFipsFuncsV1.FIPSGenRandom = FIPSGenRandom;
|
||
|
OldFipsFuncsV1.FipsBlockCBC = FipsBlockCBC;
|
||
|
|
||
|
*((PFIPS_FUNCTION_TABLE_1) Irp->AssociatedIrp.SystemBuffer) =
|
||
|
OldFipsFuncsV1;
|
||
|
|
||
|
Irp->IoStatus.Information = sizeof(OldFipsFuncsV1);
|
||
|
|
||
|
status = STATUS_SUCCESS;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
status = STATUS_BUFFER_TOO_SMALL;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Irp->IoStatus.Status = status;
|
||
|
|
||
|
IoCompleteRequest(
|
||
|
Irp,
|
||
|
IO_NO_INCREMENT
|
||
|
);
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
FipsUnload(
|
||
|
IN PDRIVER_OBJECT DriverObject
|
||
|
)
|
||
|
{
|
||
|
PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
|
||
|
|
||
|
ShutdownRNG(NULL);
|
||
|
|
||
|
// Delete the device from the system
|
||
|
IoDeleteDevice(deviceObject);
|
||
|
|
||
|
FipsDebug(
|
||
|
DEBUG_TRACE,
|
||
|
("Fips driver unloaded\n")
|
||
|
);
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
DriverEntry(
|
||
|
IN PDRIVER_OBJECT DriverObject,
|
||
|
IN PUNICODE_STRING RegistryPath
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This is the initialization routine for the synchronous NULL device driver.
|
||
|
This routine creates the device object for the NullS device and performs
|
||
|
all other driver initialization.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
DriverObject - Pointer to driver object created by the system.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
The function value is the final status from the initialization operation.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
RTL_QUERY_REGISTRY_TABLE paramTable[2];
|
||
|
UNICODE_STRING fileName, deviceName;
|
||
|
PDEVICE_OBJECT deviceObject = NULL;
|
||
|
NTSTATUS status;
|
||
|
BOOL rngInitialized = FALSE;
|
||
|
|
||
|
__try {
|
||
|
|
||
|
//
|
||
|
// Create the device object.
|
||
|
//
|
||
|
RtlInitUnicodeString(
|
||
|
&deviceName,
|
||
|
FIPS_DEVICE_NAME
|
||
|
);
|
||
|
|
||
|
status = IoCreateDevice(
|
||
|
DriverObject,
|
||
|
0 /*sizeof(DEVICE_EXTENSION)*/,
|
||
|
&deviceName,
|
||
|
FILE_DEVICE_FIPS,
|
||
|
0,
|
||
|
FALSE,
|
||
|
&deviceObject
|
||
|
);
|
||
|
|
||
|
if (!NT_SUCCESS( status )) {
|
||
|
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
deviceObject->Flags |= DO_BUFFERED_IO;
|
||
|
|
||
|
// initialize the device extension
|
||
|
/*
|
||
|
RtlZeroMemory(
|
||
|
deviceObject->DeviceExtension,
|
||
|
sizeof(PDEVICE_EXTENSION)
|
||
|
);
|
||
|
*/
|
||
|
|
||
|
// append the name of our driver to the system root path
|
||
|
RtlInitUnicodeString(
|
||
|
&fileName,
|
||
|
L"\\SystemRoot\\System32\\Drivers\\fips.sys"
|
||
|
);
|
||
|
|
||
|
status = SelfMACCheck(fileName.Buffer);
|
||
|
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
|
||
|
FipsLogError(
|
||
|
DriverObject,
|
||
|
FIPS_MAC_INCORRECT,
|
||
|
NULL,
|
||
|
status
|
||
|
);
|
||
|
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
InitializeRNG(NULL);
|
||
|
rngInitialized = TRUE;
|
||
|
|
||
|
status = AlgorithmCheck();
|
||
|
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
|
||
|
FipsLogError(
|
||
|
DriverObject,
|
||
|
FIPS_SELF_TEST_FAILURE,
|
||
|
NULL,
|
||
|
status
|
||
|
);
|
||
|
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Initialize the driver object with this device driver's entry points.
|
||
|
//
|
||
|
DriverObject->DriverUnload = FipsUnload;
|
||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = FipsCreateClose;
|
||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FipsCreateClose;
|
||
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FipsDeviceControl ;
|
||
|
}
|
||
|
__finally {
|
||
|
|
||
|
if (status != STATUS_SUCCESS) {
|
||
|
|
||
|
if (rngInitialized) {
|
||
|
|
||
|
ShutdownRNG(NULL);
|
||
|
}
|
||
|
|
||
|
if (deviceObject) {
|
||
|
|
||
|
IoDeleteDevice(deviceObject);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return status;
|
||
|
}
|