freeotfecypherdriver.c
来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 1,734 行 · 第 1/5 页
C
1,734 行
- sizeof(DIOCBufferIn->Data)
),
irpSp->Parameters.DeviceIoControl.InputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Actual check...
if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
(
sizeof(DIOC_CYPHER_DATA_IN)
- sizeof(DIOCBufferIn->Key)
- sizeof(DIOCBufferIn->IV)
- sizeof(DIOCBufferIn->Data)
+ (DIOCBufferIn->KeyLength / 8) // Bits -> Bytes
+ (DIOCBufferIn->IVLength / 8) // Bits -> Bytes
+ (DIOCBufferIn->DataLength) // Already counted in bytes
)
)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect actual: %d; got: %d)\n",
(
sizeof(DIOC_CYPHER_DATA_IN)
- sizeof(DIOCBufferIn->Key)
- sizeof(DIOCBufferIn->IV)
- sizeof(DIOCBufferIn->Data)
+ (DIOCBufferIn->KeyLength / 8) // Bits -> Bytes
+ (DIOCBufferIn->IVLength / 8) // Bits -> Bytes
+ (DIOCBufferIn->DataLength) // Already counted in bytes
),
irpSp->Parameters.DeviceIoControl.InputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Check size of OUTPUT buffer
// Actual check...
// NOTE THAT THIS USES THE DataLength MEMBER OF THE INPUT BUFFER - THE
// OUTPUT IS THE SAME SIZE AS THE INPUT
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(DIOC_CYPHER_DATA_OUT)+(DIOCBufferIn->DataLength * sizeof(DIOCBufferOut->Data))-sizeof(DIOCBufferOut->Data))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect: %d; got: %d)\n",
sizeof(DIOC_CYPHER_DATA_OUT)+DIOCBufferIn->DataLength-sizeof(DIOCBufferOut->Data),
irpSp->Parameters.DeviceIoControl.OutputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Request valid, process...
// Since the variable length members of the input buffer can't be accessed
// directly (their locations vary, depending on the size of earlier members)
// we calculate pointers so they can be accessed easily...
ptrInKey = (char*)&DIOCBufferIn->Key;
ptrInIV = ptrInKey + ((DIOCBufferIn->KeyLength / 8) * sizeof(DIOCBufferIn->Key));
ptrInData = ptrInIV + ((DIOCBufferIn->IVLength / 8) * sizeof(DIOCBufferIn->IV));
// NOTE: THIS IS ONLY DUMPED OUT IF DEBUG IS NOT ENABLED; ONLY ON
// DEBUG BUILDS.
// Normal release builds cause DEBUGOUTCYPHERDRV to be a NOP, so
// this debug code gets removed
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- Key length: %d bits\n", DIOCBufferIn->KeyLength));
for(i = 0; i < (DIOCBufferIn->KeyLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- Key [%.2d]: %.2x\n", i, ptrInKey[i]));
}
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- IV length: %d bits\n", DIOCBufferIn->IVLength));
for(i = 0; i < (DIOCBufferIn->IVLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- IV [%.2d]: %.2x\n", i, ptrInIV[i]));
}
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- Data length: %d bytes\n", DIOCBufferIn->DataLength));
for(i = 0; i < (DIOCBufferIn->DataLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- Data [%.2d]: %.2x\n", i, ptrInData[i]));
// Only dump out the first 5 bytes...
if (i >= 5)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- Data [..]: (Debug output truncated to only show first few bytes)\n"));
break;
}
}
// Sanity checks on the request wrt the cypher
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("About to get cypher details...\n"));
status = GetCypherDetails(
&(DIOCBufferIn->CypherGUID),
&CypherDetails
);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("Unable to locate requested cypher in driver\n"));
return status;
}
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Cypher details got OK.\n"));
// Input/output buffer must be a multiple of the blocksize
// Output buffer length not explicitly checked, as we already made sure
// that it's big enough to store the input data
// Note: Multiply DataLength by 8 to get bits
if ((CypherDetails.BlockSize > 0) && (((DIOCBufferIn->DataLength * 8) % CypherDetails.BlockSize) != 0))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("Length of data IN must be a multiple of the blocksize (bs: %d bits; bufSize: %d bits\n",
CypherDetails.BlockSize,
(DIOCBufferIn->DataLength * 8)));
status = STATUS_INVALID_PARAMETER;
return status;
}
// IV length must = the blocksize
if ((CypherDetails.BlockSize > 0) && (CypherDetails.BlockSize != DIOCBufferIn->IVLength))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("The cypher blocksize is greater than 0; the IV length MUST equal the cypher's blocksize (cypher blocksize: %d bits; supplied IV was: %d bits\n", CypherDetails.BlockSize, DIOCBufferIn->IVLength));
status = STATUS_INVALID_PARAMETER;
return status;
}
// KeyLength must = the keysize
if ((CypherDetails.KeySize >= 0) && (CypherDetails.KeySize != DIOCBufferIn->KeyLength))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("Keylength must = the cypher's keysize (cypher keysize: %d bits; supplied keysize: %d bits\n", CypherDetails.KeySize, DIOCBufferIn->KeyLength));
status = STATUS_INVALID_PARAMETER;
return status;
}
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Sanity checks OK\n"));
// ASCII representation of "Key".
// Number of chars/nibbles
// +1 to include NULL terminator
// This is included as an optimisation for
// ciphers which use the NIST AES API
keyASCIIBufferLen = ((DIOCBufferIn->KeyLength / 4)+1);
keyASCII = ExAllocatePool(
NonPagedPool,
keyASCIIBufferLen
);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("keyASCIIBufferLen = %d bytes\n", keyASCIIBufferLen));
// Convert the data passed in to it's ASCII representation
ConvertDataToASCIIRep(
DIOCBufferIn->KeyLength, // In bits
ptrInKey,
keyASCII
);
if (NT_SUCCESS(status))
{
// Create a tmp buffer; this is done so that we don't pass both
// the DIOC input and output buffers (the *same* buffer!) to the
// implementation function
// (Also backup dataLength for the same reason)
dataLength = DIOCBufferIn->DataLength;
tmpBuffer = ExAllocatePool(
NonPagedPool,
dataLength
);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("About to encrypt...\n"));
status = ImpCypherEncryptData(
&DIOCBufferIn->CypherGUID,
DIOCBufferIn->KeyLength, // In bits
ptrInKey,
keyASCII,
DIOCBufferIn->IVLength, // In bits
ptrInIV,
DIOCBufferIn->DataLength, // In bytes
ptrInData,
tmpBuffer
);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Done encryption: %d (want status: %d)\n", status, STATUS_SUCCESS));
RtlCopyMemory(&DIOCBufferOut->Data, tmpBuffer, dataLength);
SecZeroMemory(tmpBuffer, dataLength);
ExFreePool(tmpBuffer);
}
SecZeroMemory(keyASCII, keyASCIIBufferLen);
ExFreePool(keyASCII);
Irp->IoStatus.Information = sizeof(DIOC_CYPHER_DATA_OUT)+(dataLength * sizeof(DIOCBufferOut->Data))-sizeof(DIOCBufferOut->Data);
DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFECypherIOCTL_Encrypt\n"));
return status;
}
// =========================================================================
//
NTSTATUS
IOCTL_FreeOTFECypherIOCTL_Decrypt(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PIO_STACK_LOCATION irpSp;
PDIOC_CYPHER_DATA_IN DIOCBufferIn;
PDIOC_CYPHER_DATA_OUT DIOCBufferOut;
CYPHER CypherDetails;
char* keyASCII;
int keyASCIIBufferLen;
int dataLength;
char* tmpBuffer;
unsigned char* ptrInKey; // Pointer to where the key starts in the input buffer
unsigned char* ptrInIV; // Pointer to where the IV starts in the input buffer
unsigned char* ptrInData; // Pointer to where the data starts in the input buffer
int i;
DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFECypherIOCTL_Decrypt\n"));
irpSp = IoGetCurrentIrpStackLocation(Irp);
DIOCBufferIn = (PDIOC_CYPHER_DATA_IN)Irp->AssociatedIrp.SystemBuffer;
DIOCBufferOut = (PDIOC_CYPHER_DATA_OUT)Irp->AssociatedIrp.SystemBuffer;
// Check size of INPUT buffer
// Minimum check...
// (Done first in order to ensure that we can later access DIOCBufferIn->Data
// for actual check)
if (
irpSp->Parameters.DeviceIoControl.InputBufferLength <
(
sizeof(DIOC_CYPHER_DATA_IN)
- sizeof(DIOCBufferIn->Key)
- sizeof(DIOCBufferIn->IV)
- sizeof(DIOCBufferIn->Data)
)
)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect min: %d; got: %d)\n",
(
sizeof(DIOC_CYPHER_DATA_IN)
- sizeof(DIOCBufferIn->Key)
- sizeof(DIOCBufferIn->IV)
- sizeof(DIOCBufferIn->Data)
),
irpSp->Parameters.DeviceIoControl.InputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Actual check...
if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
(
sizeof(DIOC_CYPHER_DATA_IN)
- sizeof(DIOCBufferIn->Key)
- sizeof(DIOCBufferIn->IV)
- sizeof(DIOCBufferIn->Data)
+ ((DIOCBufferIn->KeyLength / 8) * sizeof(DIOCBufferIn->Key))
+ ((DIOCBufferIn->IVLength / 8) * sizeof(DIOCBufferIn->IV))
+ (DIOCBufferIn->DataLength * sizeof(DIOCBufferIn->Data))
)
)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect actual: %d; got: %d)\n",
(
sizeof(DIOC_CYPHER_DATA_IN)
- sizeof(DIOCBufferIn->Key)
- sizeof(DIOCBufferIn->IV)
- sizeof(DIOCBufferIn->Data)
+ ((DIOCBufferIn->KeyLength / 8) * sizeof(DIOCBufferIn->Key))
+ ((DIOCBufferIn->IVLength / 8) * sizeof(DIOCBufferIn->IV))
+ (DIOCBufferIn->DataLength * sizeof(DIOCBufferIn->Data))
),
irpSp->Parameters.DeviceIoControl.InputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Check size of OUTPUT buffer
// Actual check...
// NOTE THAT THIS USES THE DataLength MEMBER OF THE INPUT BUFFER - THE
// OUTPUT IS THE SAME SIZE AS THE INPUT
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(DIOC_CYPHER_DATA_OUT)+(DIOCBufferIn->DataLength * sizeof(DIOCBufferOut->Data))-sizeof(DIOCBufferOut->Data))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect: %d; got: %d)\n",
sizeof(DIOC_CYPHER_DATA_OUT)+DIOCBufferIn->DataLength-sizeof(DIOCBufferOut->Data),
irpSp->Parameters.DeviceIoControl.OutputBufferLength
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Request valid, process...
// Since the variable length members of the input buffer can't be accessed
// directly (their locations vary, depending on the size of earlier members)
// we calculate pointers so they can be accessed easily...
ptrInKey = (char*)&DIOCBufferIn->Key;
ptrInIV = ptrInKey + ((DIOCBufferIn->KeyLength / 8) * sizeof(DIOCBufferIn->Key));
ptrInData = ptrInIV + ((DIOCBufferIn->IVLength / 8) * sizeof(DIOCBufferIn->IV));
// NOTE: THIS IS ONLY DUMPED OUT IF DEBUG IS NOT ENABLED; ONLY ON
// DEBUG BUILDS.
// Normal release builds cause DEBUGOUTCYPHERDRV to be a NOP, so
// this debug code gets removed
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- Key length: %d bits\n", DIOCBufferIn->KeyLength));
for(i = 0; i < (DIOCBufferIn->KeyLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- Key [%.2d]: %.2x\n", i, ptrInKey[i]));
}
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- IV length: %d bits\n", DIOCBufferIn->IVLength));
for(i = 0; i < (DIOCBufferIn->IVLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- IV [%.2d]: %.2x\n", i, ptrInIV[i]));
}
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- Data length: %d bytes\n", DIOCBufferIn->DataLength));
for(i = 0; i < (DIOCBufferIn->DataLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- Data [%.2d]: %.2x\n", i, ptrInData[i]));
// Only dump out the first 5 bytes...
if (i >= 5)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, ("----- Data [..]: (Debug output truncated to only show first few bytes)\n"));
break;
}
}
// Sanity checks on the request wrt the cypher
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("About to get cypher details...\n"));
status = GetCypherDetails(
&(DIOCBufferIn->CypherGUID),
&CypherDetails
);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("Unable to locate requested cypher in driver\n"));
return status;
}
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Cypher details got OK.\n"));
// Input/output buffer must be a multiple of the blocksize
// Output buffer length not explicitly checked, as we already made sure
// that it's big enough to store the input data
// Note: Multiply DataLength by 8 to get bits
if ((CypherDetails.BlockSize > 0) && (((DIOCBufferIn->DataLength * 8) % CypherDetails.BlockSize) != 0))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("Length of data IN must be a multiple of the blocksize (bs: %d bits; bufSize: %d bits\n",
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?