📄 freeotfe4pda.c
字号:
{
// If a IV cypher algorithm *was* passed in, get it's details and store them
if (
(DIOCBuffer->IVCypherDeviceName[0] != 0) &&
(!(IsEqualGUID(&(DIOCBuffer->IVCypherGUID), &FREEOTFE_NULL_GUID)))
)
{
devContext->IVCypher.CypherGUID = DIOCBuffer->IVCypherGUID;
allOK = GetDeviceDetailsCypher(
(WCHAR*)&DIOCBuffer->IVCypherDeviceName,
&DIOCBuffer->IVCypherGUID,
&devContext->IVCypher
);
if (!(allOK))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to get IV cypher device\n")));
}
}
else
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("No IV cypher specified.\n")));
}
}
// --- OBTAIN THE MAIN CYPHER DRIVER ---
if (allOK)
{
devContext->MainCypher.CypherGUID = DIOCBuffer->MainCypherGUID;
allOK = GetDeviceDetailsCypher(
(WCHAR*)&DIOCBuffer->MainCypherDeviceName,
&DIOCBuffer->MainCypherGUID,
&devContext->MainCypher
);
if (!(allOK))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to get main cypher device\n")));
}
}
// Identify pointers to variable length members of mount struct
if (allOK)
{
// This may seem a little weird, but is required as the position of various members
// within the struct is variable
ptrMasterKey = (PCHAR)&(DIOCBuffer->MasterKey);
ptrVolumeIV = ptrMasterKey + (DIOCBuffer->MasterKeyLength / 8);
ptrMetaData = ptrVolumeIV + (DIOCBuffer->VolumeIVLength / 8);
}
// Copy master key...
if (allOK)
{
devContext->MasterKeyLength = DIOCBuffer->MasterKeyLength;
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("MasterKeyLength: %d bits\n"), devContext->MasterKeyLength));
devContext->MasterKey = malloc((devContext->MasterKeyLength / 8));
if (devContext->MasterKey == NULL)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to malloc memory for MasterKey\n")));
allOK = FALSE;
}
else
{
memcpy(
devContext->MasterKey,
ptrMasterKey,
(devContext->MasterKeyLength / 8)
);
for(i = 0; i < (devContext->MasterKeyLength / 8); i++)
{
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- MasterKey [%.2d]: %.2x\n"), i, devContext->MasterKey[i]));
}
// Divide by 8 to get bytes from bits, then multiply by 2 to get nibbles
// Note: +2 in order to store two terminating NULLs; just in case
devContext->MasterKeyASCII = malloc((((devContext->MasterKeyLength / 8) * 2) + 2));
if (devContext->MasterKeyASCII == NULL)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to malloc memory for MasterKeyASCII\n")));
allOK = FALSE;
}
else
{
// Convert the data passed in to it's ASCII representation
ConvertDataToASCIIRep(
devContext->MasterKeyLength,
devContext->MasterKey,
devContext->MasterKeyASCII
);
// 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, (TEXT("----- Key as ASCII: %s\n"), devContext->MasterKeyASCII));
}
}
}
if (allOK)
{
// --- HASH THE MASTER KEY FOR ESSIV (IV) USE ---
// WARNING: Must get the cypher, hash and SectorIVGenMethod *first*
// Note: Because this is for ESSIV use, we only keep the first (cypher keysize) bits of
// the hash; rightpadding as necessary
// We use a temp buffer as we can't guarantee how long the hash output will be
// e.g. if it's a variable length hash like "unhashed/NULL"
tmpHashBufferUsed = (sizeof(tmpHashBuffer) * 8); // Convert from bytes to bits
// If we're not using ESSIV to generate IVs, we don't bother hashing the key to generate
// an ESSIV key; we act as though the hash algorithm just returned no data.
if (devContext->SectorIVGenMethod != SCTRIVGEN_ESSIV)
{
tmpHashBufferUsed = 0;
}
else
{
allOK = (DataHash(
&(devContext->IVHash),
devContext->MasterKeyLength,
devContext->MasterKey,
&tmpHashBufferUsed, // In bits
tmpHashBuffer
) == STATUS_SUCCESS);
if (!(allOK))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to hash key for ESSIV IVs\n")));
// Overwrite potentially sensitive data in temp buffer...
SecZeroMemory(tmpHashBuffer, sizeof(tmpHashBuffer));
}
if (allOK)
{
devContext->ESSIVKeyLength = tmpHashBufferUsed;
useHashBits = tmpHashBufferUsed;
// Handle if the keysize is fixed
if (devContext->IVCypher.Details.KeySize >= 0)
{
devContext->ESSIVKeyLength = devContext->IVCypher.Details.KeySize;
useHashBits = min(tmpHashBufferUsed, (unsigned int)devContext->IVCypher.Details.KeySize);
}
// Divide by 8 to get bytes from bits
devContext->ESSIVKey = malloc((devContext->ESSIVKeyLength / 8));
if (devContext->ESSIVKey == NULL)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to malloc memory for ESSIVKey\n")));
allOK = FALSE;
}
}
if (allOK)
{
// Zero the buffer in in order to ensure that unused buffer
// remaining after the key is zero'd, just in case the cypher
// used is badly behaved
memset(devContext->ESSIVKey, 0, (devContext->ESSIVKeyLength / 8));
memcpy(
devContext->ESSIVKey,
tmpHashBuffer,
(useHashBits / 8)
);
// NOTE: THE ESSIV 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, (TEXT("----- ESSIV key length: %d bits\n"), devContext->ESSIVKeyLength));
for(i = 0; i < (devContext->ESSIVKeyLength / 8); i++)
{
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- ESSIV key [%.2d]: %.2x\n"), i, devContext->ESSIVKey[i]));
}
// Divide by 8 to get bytes from bits, then multiply by 2 to get nibbles
// Note: +2 in order to store two terminating NULLs; just in case
devContext->ESSIVKeyASCII = malloc(
(((devContext->ESSIVKeyLength / 8) * 2) + 2)
);
if (devContext->ESSIVKeyASCII == NULL)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to malloc memory for ESSIVKeyASCII\n")));
allOK = FALSE;
}
}
if (allOK)
{
// Convert the data passed in to it's ASCII representation
ConvertDataToASCIIRep(
devContext->ESSIVKeyLength,
devContext->ESSIVKey,
devContext->ESSIVKeyASCII
);
// 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, (TEXT("----- ESSIV key as ASCII: %s\n"), devContext->ESSIVKeyASCII));
}
}
}
// Copy volume IV...
if (allOK)
{
devContext->VolumeIVLength = DIOCBuffer->VolumeIVLength;
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("VolumeIVLength: %d bits\n"), devContext->VolumeIVLength));
devContext->VolumeIV = malloc((devContext->VolumeIVLength / 8));
if (devContext->VolumeIV == NULL)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to malloc memory for VolumeIV\n")));
allOK = FALSE;
}
else
{
memcpy(
devContext->VolumeIV,
ptrVolumeIV,
(devContext->VolumeIVLength / 8)
);
for(i = 0; i < (devContext->VolumeIVLength / 8); i++)
{
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- VolumeIV [%.2d]: %.2x\n"), i, devContext->VolumeIV[i]));
}
}
}
// Initialize various simple members...
if (allOK)
{
devContext->VolumeFlags = DIOCBuffer->VolumeFlags;
}
// Copy any user metadata
if (allOK)
{
devContext->MetaDataLength = DIOCBuffer->MetaDataLength;
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("MetaDataLength: %d bytes\n"), devContext->MetaDataLength));
devContext->MetaData = malloc(devContext->MetaDataLength);
if (devContext->MetaData == NULL)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to malloc memory for MetaData\n")));
allOK = FALSE;
}
else
{
memcpy(
devContext->MetaData,
ptrMetaData,
devContext->MetaDataLength
);
for(i = 0; i < (devContext->MetaDataLength); i++)
{
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- MetaData [%.2d]: %.2x\n"), i, devContext->MetaData[i]));
}
}
}
// Store the device context, obtain our device mgr handle
retval = 0;
if (allOK)
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("Obtaining device handle...\n")));
retval = contextMgrDevice_AddDevice(devContext);
}
if (retval == 0)
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("FAILED TO INIT.\n")));
OverwriteDeviceSensitive(devContext);
SecZeroAndFreeMemory(devContext, sizeof(devContext));
}
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("Device handle returned: 0x%0.8x\n"), retval));
DEBUGOUTMAINDRV(DEBUGLEV_EXIT, (TEXT("DSK_Init\n")));
return retval;
}
// =========================================================================
// Overwrite sensitive parts of the specified device's extension
// Given a device context, cleardown, free off and overwrite all sensitive
// parts (e.g. encryption/decryption keys, etc)
// !!! WARNING !!!
// This must only ever be called on a disk device which has been UNMOUNTED,
// with nothing remaining to be processed
void
OverwriteDeviceSensitive(DEVICE_CONTEXT* devContext)
{
// Mutex...
DeleteCriticalSection(devContext->CriticalSection);
SecZeroAndFreeMemory(
devContext->CriticalSection,
sizeof(*devContext->CriticalSection)
);
// Number of times opened
devContext->OpenCount = 0;
// Flag if a volume is mounted or not
devContext->Mounted = FALSE;
// User app device handle
devContext->UserSpaceDeviceHandle = 0;
// Registry info...
RegDetailsFree(NULL, NULL, &devContext->RegdetailsActive);
// Flag if a volume is being dismounted or not
devContext->DismountPending = TRUE;
// Mount source (e.g. the volume file is a partition or file)
devContext->MountSource = MNTSRC_UNKNOWN;
// Filename of any mounted volume
SecZeroAndFreeWCHARMemory(devContext->zzFilename);
// Mountpoint
SecZeroAndFreeWCHARMemory(devContext->Mountpoint);
// Handle to the file
if (devContext->FileHandle != NULL)
{
CloseHandle(devContext->FileHandle);
}
devContext->FileHandle = NULL;
// Flag if file attributes have been stored (e.g. FALSE for partitions, etc)
devContext->FileAttributesStored = FALSE;
devContext->FileAttributes = 0;
devContext->FileTimestampsStored = FALSE;
// If stored, the file timestamps
SecZeroMemory(&devContext->CreationTime, sizeof(devContext->CreationTime));
SecZeroMemory(&devContext->LastAccessTime, sizeof(devContext->LastAccessTime));
SecZeroMemory(&devContext->LastWriteTime, sizeof(devContext->LastWriteTime));
// Start of encrypted data within the file
devContext->DataOffset.QuadPart = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -