freeotfe.c
来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 1,966 行 · 第 1/5 页
C
1,966 行
&fileAttributes
);
if (NT_SUCCESS(status))
{
if (DoWrite)
{
status = ZwWriteFile(
fileHandle,
NULL,
NULL,
NULL,
&ioStatusBlock,
Data,
DataLength,
&Offset,
NULL
);
}
else
{
status = ZwReadFile(
fileHandle,
NULL,
NULL,
NULL,
&ioStatusBlock,
Data,
DataLength,
&Offset,
NULL
);
}
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Status: %d; wanted: %d.\n", status, STATUS_SUCCESS));
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Read/written: %d bytes (only valid if status is success).\n", ioStatusBlock.Information));
if (!(NT_SUCCESS(status)))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Unable to read/write raw (%d %d).\n", status, ioStatusBlock.Status));
status = STATUS_INVALID_PARAMETER;
}
else if (ioStatusBlock.Information != DataLength)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Failed to read/write all data. Transferred: %d bytes; expected: %d bytes.\n", ioStatusBlock.Information, DataLength));
status = STATUS_INVALID_PARAMETER;
}
// Return value ignored
FileClose(
&fileHandle,
fileAttributesStored,
&fileAttributes,
&ioStatusBlock
);
}
// Return value ignored
ClientSecurityDestroy(&ClientContext);
DEBUGOUTMAINDRV(DEBUGLEV_EXIT, ("SetGetRawUnicode\n"));
return status;
}
// =========================================================================
// Derive a key
NTSTATUS
IOCTL_FreeOTFEIOCTL_DeriveKey(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PIO_STACK_LOCATION irpSp;
PDIOC_DERIVE_KEY_IN DIOCBufferIn;
PDIOC_DERIVE_KEY_OUT DIOCBufferOut;
unsigned char* tmpOutput;
int tmpLengthBits; // In *bits*
int userBufferSizeBytes; // In *bytes*
unsigned int useBits; // In *bits*
int lengthWanted; // In *bits*
unsigned int i;
DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEIOCTL_DeriveKey\n"));
status = STATUS_SUCCESS;
irpSp = IoGetCurrentIrpStackLocation(Irp);
DIOCBufferIn = (PDIOC_DERIVE_KEY_IN)Irp->AssociatedIrp.SystemBuffer;
DIOCBufferOut = (PDIOC_DERIVE_KEY_OUT)Irp->AssociatedIrp.SystemBuffer;
// Check size of INPUT buffer
// Minimum check...
// (Done first in order to ensure that we can later access length related
// members for actual check)
if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
(
sizeof(DIOC_DERIVE_KEY_IN)
- sizeof(DIOCBufferIn->Password)
- sizeof(DIOCBufferIn->Salt)
)
)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect min: %d; got: %d)\n",
(
sizeof(DIOC_DERIVE_KEY_IN)
- sizeof(DIOCBufferIn->Password)
- sizeof(DIOCBufferIn->Salt)
),
irpSp->Parameters.DeviceIoControl.InputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Actual check...
if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
(
sizeof(DIOC_DERIVE_KEY_IN)
- sizeof(DIOCBufferIn->Password)
- sizeof(DIOCBufferIn->Salt)
+ (DIOCBufferIn->PasswordLength / 8)
+ (DIOCBufferIn->SaltLength / 8)
)
)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect actual: %d; got: %d)\n",
(
sizeof(DIOC_DERIVE_KEY_IN)
- sizeof(DIOCBufferIn->Password)
- sizeof(DIOCBufferIn->Salt)
+ (DIOCBufferIn->PasswordLength / 8)
+ (DIOCBufferIn->SaltLength / 8)
),
irpSp->Parameters.DeviceIoControl.InputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Check size of OUTPUT buffer
// Minimum check...
// (Done first in order to ensure that we can later access length related
// members for actual check)
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(DIOC_DERIVE_KEY_OUT)-sizeof(DIOCBufferOut->DerivedKey))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect min: %d; got: %d)\n",
sizeof(DIOC_DERIVE_KEY_OUT)-sizeof(DIOCBufferOut->DerivedKey),
irpSp->Parameters.DeviceIoControl.OutputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Request valid so far, process...
// We have to allocate a buffer to hold the output, before it can be copied
// out to the output buffer; otherwise, the input buffer gets garbled as
// data is written to the output buffer
// Match the user's buffer; if it's too small, the operation will kick
// it out
// This calculates the size of the variable part of the struct
// Yes, this should be correct: The total size of the user's output buffer,
// less the size of the struct - but then plus the size of
// the variable parts reserved within the buffer
userBufferSizeBytes = (irpSp->Parameters.DeviceIoControl.OutputBufferLength) -
sizeof(DIOCBufferOut) +
sizeof(DIOCBufferOut->DerivedKey);
tmpOutput = ExAllocatePool(
NonPagedPool,
userBufferSizeBytes
);
// The size of the buffer in bits; the algorithm will read this value, then
// overwrite it with the actual size of the output (in bits)
tmpLengthBits = (userBufferSizeBytes * 8);
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Allocated output buffer for: %d bits\n", tmpLengthBits));
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("About to process...\n"));
// This call runs the correct algorithm and generates the output
if (DIOCBufferIn->LengthWanted == 0)
{
// Optimisation - if the user wants a zero length output, don't
// bother processing, just return zero length output.
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Zero length output requested; returning nothing\n"));
tmpLengthBits = 0;
status = STATUS_SUCCESS;
}
else
{
status = DeriveKey(
DIOCBufferIn->KDFAlgorithm,
DIOCBufferIn->HashDeviceName,
DIOCBufferIn->HashGUID,
DIOCBufferIn->CypherDeviceName,
DIOCBufferIn->CypherGUID,
DIOCBufferIn->Iterations,
DIOCBufferIn->LengthWanted,
DIOCBufferIn->PasswordLength, // In bits
(unsigned char*)&DIOCBufferIn->Password, // Variable length
DIOCBufferIn->SaltLength, // In bits
// This may seem a little weird, but is required as the
// position of the salt within the struct is variable
&DIOCBufferIn->Password[(DIOCBufferIn->PasswordLength / 8)], // Variable length
&tmpLengthBits, // In bits
(unsigned char*)tmpOutput // Variable length
);
}
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("DK Done with status: %d (want status: %d)\n", status, STATUS_SUCCESS));
if (NT_SUCCESS(status))
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("tmp buffer was: %d bits, output was %d bits\n", (userBufferSizeBytes * 8), tmpLengthBits));
// Preserve input buffer value, to ensure we don't overwrite it with
// the output buffer
lengthWanted = DIOCBufferIn->LengthWanted;
// Actual check...
// Ensure output DIOC butter is large enough to store the output
// Note that we can't carry out this check until we've created the
// output value, in case the algorithm used produces variable length
// output
// If the user specified an output length, we only use those bits
if (lengthWanted >= 0)
{
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(DIOC_DERIVE_KEY_OUT)+(lengthWanted/8)-sizeof(DIOCBufferOut->DerivedKey))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect actual: %d; got: %d)\n",
sizeof(DIOC_DERIVE_KEY_OUT)+(lengthWanted/8)-sizeof(DIOCBufferOut->DerivedKey),
irpSp->Parameters.DeviceIoControl.OutputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
}
else
{
// If the algorithm doens't generate enough bits, we right-pad
// with NULLs
if (lengthWanted > tmpLengthBits)
{
// Cleardown the buffer beyond the output
RtlZeroMemory(
&DIOCBufferOut->DerivedKey,
(lengthWanted / 8)
);
useBits = tmpLengthBits;
}
else
{
useBits = lengthWanted;
}
RtlCopyMemory(&DIOCBufferOut->DerivedKey, tmpOutput, (useBits / 8));
DIOCBufferOut->DerivedKeyLength = lengthWanted;
}
}
else
// User didn't specify an output length - we use the entire
// algorithm's output
{
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(DIOC_DERIVE_KEY_OUT)+(tmpLengthBits/8)-sizeof(DIOCBufferOut->DerivedKey))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect actual: %d; got: %d)\n",
sizeof(DIOC_DERIVE_KEY_OUT)+(tmpLengthBits/8)-sizeof(DIOCBufferOut->DerivedKey),
irpSp->Parameters.DeviceIoControl.OutputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
}
else
{
RtlCopyMemory(&DIOCBufferOut->DerivedKey, tmpOutput, (tmpLengthBits / 8));
DIOCBufferOut->DerivedKeyLength = tmpLengthBits;
}
}
Irp->IoStatus.Information = sizeof(DIOC_DERIVE_KEY_OUT)+(DIOCBufferOut->DerivedKeyLength/8)-sizeof(DIOCBufferOut->DerivedKey);
}
else
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("FAILED"));
}
SecZeroMemory(tmpOutput, userBufferSizeBytes);
ExFreePool(tmpOutput);
if (NT_SUCCESS(status))
{
// NOTE: THE KEY IS ONLY DUMPED OUT IF DEBUG IS ENABLED; ONLY ON
// DEBUG BUILDS.
// Normal release builds cause DEBUGOUTMAINDRV to be a NOP, so
// this debug code gets removed
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("----- DerivedKey length: %d bits\n", DIOCBufferOut->DerivedKeyLength));
for(i = 0; i < (DIOCBufferOut->DerivedKeyLength / 8); i++)
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("----- DerivedKey [%.2d]: %.2x\n", i, DIOCBufferOut->DerivedKey[i]));
}
}
DEBUGOUTMAINDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFEIOCTL_DeriveKey\n"));
return status;
}
// =========================================================================
// Generate a MAC
NTSTATUS
IOCTL_FreeOTFEIOCTL_GenerateMAC(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PIO_STACK_LOCATION irpSp;
PDIOC_GENERATE_MAC_IN DIOCBufferIn;
PDIOC_GENERATE_MAC_OUT DIOCBufferOut;
unsigned char* tmpOutput;
int tmpLengthBits; // In *bits*
int userBufferSizeBytes; // In *bytes*
unsigned int useBits; // In *bits*
int lengthWanted; // In *bits*
unsigned int i;
DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEIOCTL_GenerateMAC\n"));
status = STATUS_SUCCESS;
irpSp = IoGetCurrentIrpStackLocation(Irp);
DIOCBufferIn = (PDIOC_GENERATE_MAC_IN)Irp->AssociatedIrp.SystemBuffer;
DIOCBufferOut = (PDIOC_GENERATE_MAC_OUT)Irp->AssociatedIrp.SystemBuffer;
// Check size of INPUT buffer
// Minimum check...
// (Done first in order to ensure that we can later access length related
// members for actual check)
if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
(
sizeof(DIOC_GENERATE_MAC_IN)
- sizeof(DIOCBufferIn->Key)
- sizeof(DIOCBufferIn->Data)
)
)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect min: %d; got: %d)\n",
(
sizeof(DIOC_GENERATE_MAC_IN)
- sizeof(DIOCBufferIn->Key)
- sizeof(DIOCBufferIn->Data)
),
irpSp->Parameters.DeviceIoControl.InputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Actual check...
if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
(
sizeof(DIOC_GENERATE_MAC_IN)
- sizeof(DIOCBufferIn->Key)
- sizeof(DIOCBufferIn->Data)
+ (DIOCBufferIn->KeyLength / 8)
+ (DIOCBufferIn->DataLength / 8)
)
)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect actual: %d; got: %d)\n",
(
sizeof(DIOC_GEN
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?