📄 freeotfe4pdacypherdriver.c
字号:
// Description: FreeOTFE Cypher Device Driver
// By Sarah Dean
// Email: sdean12@sdean12.org
// WWW: http://www.FreeOTFE.org/
//
// -----------------------------------------------------------------------------
//
#include <stdio.h>
#include "SDUGeneral.h"
#include "FreeOTFE4PDACypherDriver.h"
#include "FreeOTFECypherAPICommon.h"
#include "FreeOTFEDebug.h"
#include "FreeOTFElib.h"
#include "FreeOTFE4PDAlib.h"
#include "FreeOTFECypherImpl.h"
#include "FreeOTFEPlatform.h"
#include "FreeOTFE4PDACypherAPI.h"
// =========================================================================
BOOL WINAPI DllMain(
HANDLE hinstDLL,
DWORD dwReason,
LPVOID lpvReserved
)
{
BOOL retval = TRUE;
int majorVersion;
int minorVersion;
int revisionVersion;
int buildVersion;
#if DBG
static BOOL setDebugLevel = FALSE;
// Default to all on
// ULONG default_DebugLevel = 0xFFFFFFFF;
// Default to all except verbose debug
ULONG default_DebugLevel =
DEBUGLEV_ERROR |
DEBUGLEV_WARN |
DEBUGLEV_INFO |
DEBUGLEV_ENTER |
DEBUGLEV_EXIT;
DWORD useDebugLevel;
DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, (TEXT("DllMain\n")));
if (!(setDebugLevel))
{
useDebugLevel = ReadDebugLevelFromFile(DEBUGLEVEL_FILE);
if (useDebugLevel == FREEOTFE_DEBUG_LEVEL_NOT_READ)
{
useDebugLevel = default_DebugLevel;
}
FreeOTFEDebugLevel = useDebugLevel;
setDebugLevel = TRUE;
}
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Debug level : %d\n"), FreeOTFEDebugLevel));
#endif
if (!(SDUGetVersionInfo(
NULL,
&majorVersion,
&minorVersion,
&revisionVersion,
&buildVersion
)))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Driver version: <unable to determine>\n")));
}
else
{
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Driver version: v%02d.%02d.%02d.%04d\n"),
majorVersion,
minorVersion,
revisionVersion,
buildVersion
));
}
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
{
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("DLL_PROCESS_ATTACH\n")));
// We really don't care about getting
// DLL_THREAD_ATTACH/DLL_THREAD_DETACH calls; disable
DisableThreadLibraryCalls(hinstDLL);
break;
}
case DLL_THREAD_ATTACH:
{
// This should never be reached; we disable thread
// DLL_THREAD_ATTACH/DLL_THREAD_DETACH calls
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("DLL_THREAD_ATTACH\n")));
break;
}
case DLL_THREAD_DETACH:
{
// This should never be reached; we disable thread
// DLL_THREAD_ATTACH/DLL_THREAD_DETACH calls
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("DLL_THREAD_DETACH\n")));
break;
}
case DLL_PROCESS_DETACH:
{
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("DLL_PROCESS_DETACH\n")));
break;
}
}
DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, (TEXT("DllMain\n")));
return retval;
}
// =========================================================================
// IOCTL to get cypher driver identification
DWORD
CypherIdentifyDriver(
DIOC_CYPHER_IDENTIFYDRIVER* Buffer
)
{
DWORD status = STATUS_SUCCESS;
CYPHER_DRIVER_INFO tmpDriverInfo;
DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, (TEXT("IdentifyDriver\n")));
// Populate output buffer
ImpCypherDriverExtDetailsInit(&tmpDriverInfo);
Buffer->DriverGUID = tmpDriverInfo.DriverGUID;
FREEOTFE_MEMZERO(Buffer->Title, sizeof(Buffer->Title));
FREEOTFE_MEMCPY(
Buffer->Title,
tmpDriverInfo.DriverTitle,
strlen(tmpDriverInfo.DriverTitle)
);
Buffer->VersionID = tmpDriverInfo.DriverVersionID;
Buffer->CountCyphers = tmpDriverInfo.CypherCount;
ImpCypherDriverExtDetailsCleardown(&tmpDriverInfo);
DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, (TEXT("IdentifyDriver\n")));
return status;
}
// =========================================================================
// IOCTL to get cyphers supported
DWORD
CypherIdentifySupported(
int BufferSize, // In bytes
DIOC_CYPHER_IDENTIFYSUPPORTED* Buffer
)
{
DWORD status = STATUS_SUCCESS;
CYPHER_DRIVER_INFO tmpDriverInfo;
DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, (TEXT("IdentifySupported\n")));
// Check size of OUTPUT buffer
if (BufferSize <
sizeof(*Buffer)-sizeof(Buffer->Cyphers))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("outBuffer size wrong size (expect min: %d; got: %d)\n"),
sizeof(*Buffer)-sizeof(Buffer->Cyphers),
BufferSize
));
status = STATUS_INVALID_BUFFER_SIZE;
return status;
}
// Request valid, process...
// Setup the input parameter passed to ImpCypherIdentifySupported, so that it's aware
// of how large the array of cypher details is
Buffer->BufCount =
(
// The size of the buffer, less the array of cypher details
BufferSize -
(sizeof(*Buffer)-sizeof(Buffer->Cyphers))
) /
// Divide by the size of each cypher details struct to give the array length
sizeof(Buffer->Cyphers);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Request is sufficiently large to store %d cypher details\n"), Buffer->BufCount));
ImpCypherDriverExtDetailsInit(&tmpDriverInfo);
if (Buffer->BufCount < tmpDriverInfo.CypherCount)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("outBuffer not large enough to store enough (can store: %d, requires: )\n"),
Buffer->BufCount,
tmpDriverInfo.CypherCount
));
status = STATUS_INVALID_BUFFER_SIZE;
ImpCypherDriverExtDetailsCleardown(&tmpDriverInfo);
return status;
}
// Request valid, process...
Buffer->BufCount = tmpDriverInfo.CypherCount;
FREEOTFE_MEMCPY(
&Buffer->Cyphers[0],
tmpDriverInfo.CypherDetails,
(sizeof(CYPHER) * tmpDriverInfo.CypherCount)
);
ImpCypherDriverExtDetailsCleardown(&tmpDriverInfo);
DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, (TEXT("IdentifySupported\n")));
return status;
}
// =========================================================================
//
DWORD
CypherEncryptWithASCII(
IN GUID* CypherGUID,
IN int KeyLength, // In bits
IN char *Key,
IN char *KeyASCII, // ASCII representation of "Key"
IN int IVLength, // In bits
IN char *IV,
IN int PlaintextLength, // In bytes
IN char *PlaintextData,
OUT char *CyphertextData
)
{
DWORD status;
DEBUGOUTHASHDRV(DEBUGLEV_ENTER, (TEXT("EncryptWithASCII\n")));
status = ImpCypherEncryptData(
CypherGUID,
KeyLength,
Key,
KeyASCII,
IVLength,
IV,
PlaintextLength,
PlaintextData,
CyphertextData
);
DEBUGOUTHASHDRV(DEBUGLEV_EXIT, (TEXT("EncryptWithASCII\n")));
return status;
}
// =========================================================================
//
DWORD
CypherEncrypt(
IN DWORD BufferInLen,
IN DIOC_CYPHER_DATA_IN* BufferIn,
IN DWORD BufferOutLen,
IN DIOC_CYPHER_DATA_OUT* BufferOut
)
{
DWORD status;
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, (TEXT("Encrypt\n")));
// 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*)&BufferIn->Key;
ptrInIV = ptrInKey + ((BufferIn->KeyLength / 8) * sizeof(BufferIn->Key));
ptrInData = ptrInIV + ((BufferIn->IVLength / 8) * sizeof(BufferIn->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, (TEXT("----- Key length: %d bits\n"), BufferIn->KeyLength));
for(i = 0; i < (BufferIn->KeyLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Key [%.2d]: %.2x\n"), i, ptrInKey[i]));
}
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- IV length: %d bits\n"), BufferIn->IVLength));
for(i = 0; i < (BufferIn->IVLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- IV [%.2d]: %.2x\n"), i, ptrInIV[i]));
}
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Data length: %d bytes\n"), BufferIn->DataLength));
for(i = 0; i < (BufferIn->DataLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Data [%.2d]: %.2x\n"), i, ptrInData[i]));
// Only dump out the first 5 bytes...
if (i >= 5)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Data [..]: (Debug output truncated to only show first few bytes)\n")));
break;
}
}
// Sanity checks on the request wrt the cypher
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -