⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driverinterfacetwo.c

📁 文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2, MD4, MD5, RIPEMD-128, RIPEMD-160, SHA-1, SHA-224, SHA-256,
💻 C
📖 第 1 页 / 共 5 页
字号:
// Description: 
// By Sarah Dean
// Email: sdean12@sdean12.org
// WWW:   http://www.FreeOTFE.org/
//
// -----------------------------------------------------------------------------
//

#include <storemgr.h>  // Required for STORAGE_DEVICE_TYPE_PCCARD, etc

#include "SDUGeneral.h"
#include "SDUHexDump.h"

#include "FreeOTFENULLGUID.h"
#include "DriverInterface.h"
#include "DriverInterfaceTwo.h"
#include "FreeOTFEDebug.h"
#include "FreeOTFEAPIConstsCommon.h"
#include "FreeOTFEPlatform.h"
#include "FreeOTFElib.h"
#include "FreeOTFE4PDAlib.h"
#include "DriverInterfaceHash.h"
#include "DriverInterfaceCypher.h"
#include "DriverInterfaceCommon.h"


// =========================================================================
// Constants...

// In *bits*
#define CDB_MAX_MAC_LENGTH   512 

// These are artifical maximums; they must be enough to store the results of
// the DIOC calls when the amount of data output is variable 
// In *bits*
#define MAX_DERIVED_KEY_LENGTH  (1024 * 1024)
// In *bits*
#define MAX_MAC_LENGTH          (1024 * 1024)


// In *bits*
#define MML 512

#define CDB_VERSION 3


// =========================================================================
// Forward declarations...
void driver_UnloadMainDLL(MODULE_DETAILS_MAIN* DLLDetails);

BOOL
_driver_BackupRestoreCDB(
    WCHAR* SrcFilename,
    LARGE_INTEGER SrcOffset,
    WCHAR* DestFilename,
    LARGE_INTEGER DestOffset
);

// =========================================================================
// Note: Ignores any random padding data
BOOL _driver_ParseVolumeDetailsBlock(
    unsigned int rawDataSize,  // In bytes
    FREEOTFEBYTE* rawData,
    CDB_DETAILS* volumeDetailsBlock
)
{
    BOOL allOK = TRUE;
    FREEOTFEBYTE* ptr;
    int CDBFormatID;
    LARGE_INTEGER tmpLargeInteger;
    DWORD tmpDWORD;
    char tmpChar;

    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("_driver_ParseVolumeDetailsBlock\n")));

    ptr = rawData;

    if (allOK)
        {
        // 8 bits: CDB Format ID...
        ptr = SDUUnpack_char(ptr, &tmpChar);
        CDBFormatID = tmpChar;
		volumeDetailsBlock->CDBFormatID = CDBFormatID;

        // We only support CDB v3 format and later (i.e. Desktop FreeOTFE
        // v00.54.00 and later)
        if (CDBFormatID < 3)
            {
            DEBUGOUTGUI(DEBUGLEV_WARN, (TEXT("Unsupported CDB version (CDB is version: %d)\n"), CDBFormatID));
            allOK = FALSE;
            }
        }

    if (allOK)
        {
        // 32 bits: Volume flags...
        ptr = SDUUnpack_DWORD(ptr, &tmpDWORD);
        volumeDetailsBlock->VolumeFlags = tmpDWORD;
        }

    if (allOK)
        {
        // 64 bits: Partition length...
        ptr = SDUUnpack_LARGE_INTEGER(ptr, &tmpLargeInteger);
        volumeDetailsBlock->PartitionSize.QuadPart = tmpLargeInteger.QuadPart;
        }

    if (allOK)
        {
        // 32 bits: Master key length...
        ptr = SDUUnpack_DWORD(ptr, &tmpDWORD);
        volumeDetailsBlock->MasterKeyLength = tmpDWORD;

        // Note: If decrypted badly, can't rely on: criticalData.MasterKeyLen to be
        //       valid
        //       We check if the volume details block's master key length implies
        //       would put idx beyond the amount of data we have
        if (((ptr - rawData) + (volumeDetailsBlock->MasterKeyLength / 8)) >
              rawDataSize) 
            {
            DEBUGOUTGUI(DEBUGLEV_WARN, (TEXT("Invalid MasterKeyLength in CDB (length: %d *bits*)\n"), volumeDetailsBlock->MasterKeyLength));
            allOK = FALSE;
            }
        }

    if (allOK)
        {
        // Variable bits: Master key...
        volumeDetailsBlock->MasterKey = malloc((volumeDetailsBlock->MasterKeyLength / 8));
        if (volumeDetailsBlock->MasterKey == NULL)
            {
            DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("Unable to malloc memory for MasterKey (length: %d *bits*)\n"), volumeDetailsBlock->MasterKeyLength));
            allOK = FALSE;
            }
        else
            {
            memcpy(volumeDetailsBlock->MasterKey, ptr, (volumeDetailsBlock->MasterKeyLength / 8));
            ptr += (volumeDetailsBlock->MasterKeyLength / 8);
            }
        }

    if (allOK)
        {
        // 8 bits: Requested drive letter...
        // Not used under WinCE, but preserved in case user wants to change
        // password
        ptr = SDUUnpack_char(ptr, &tmpChar);
        volumeDetailsBlock->DefaultDrive = tmpChar;
        }

    if (allOK)
        {
        // 32 bits: Volume IV length...
        ptr = SDUUnpack_DWORD(ptr, &tmpDWORD);
        volumeDetailsBlock->VolumeIVLength = tmpDWORD;

        // Note: If decrypted badly, can't rely on: criticalData.VolumeIVLength to be
        //       valid
        //       We check if the volume details block's master key length implies
        //       would put idx beyond the amount of data we have
        if (((ptr - rawData) + (volumeDetailsBlock->VolumeIVLength / 8)) >
              rawDataSize) 
            {
            DEBUGOUTGUI(DEBUGLEV_WARN, (TEXT("Invalid VolumeIVLength in CDB (length: %d *bits*)\n"), volumeDetailsBlock->VolumeIVLength));
            allOK = FALSE;
            }
        }

    if (allOK)
        {
        // Variable bits: Volume IV...
        volumeDetailsBlock->VolumeIV = malloc((volumeDetailsBlock->VolumeIVLength / 8));
        if (volumeDetailsBlock->VolumeIV == NULL)
            {
            DEBUGOUTGUI(DEBUGLEV_ERROR, (TEXT("Unable to malloc memory for VolumeIV (length: %d *bits*)\n"), volumeDetailsBlock->VolumeIVLength));
            allOK = FALSE;
            }
        else
            {
            memcpy(volumeDetailsBlock->VolumeIV, ptr, (volumeDetailsBlock->VolumeIVLength / 8));
            ptr += (volumeDetailsBlock->VolumeIVLength / 8);
            }
        }

    if (allOK)
        {
        // 8 bits: Sector IV generation method...
        ptr = SDUUnpack_char(ptr, &tmpChar);
        volumeDetailsBlock->SectorIVGenMethod = (SECTOR_IV_GEN_METHOD)tmpChar;
        }


    DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("_driver_ParseVolumeDetailsBlock\n")));
    return allOK;
}


// =========================================================================
// Key derivation function
// Note: *Caller* is responsible for freeing of DK
BOOL driver_DeriveKey(
    MODULE_DETAILS_MAIN* mainDriver,

    KDF_ALGORITHM kdfAlgorithm,
    WCHAR* hashKernelModeDeviceName,
    GUID hashGUID,
    WCHAR* cypherKernelModeDeviceName,
    GUID cypherGUID,
    char* Password,
    FREEOTFEBYTE* Salt,
    unsigned int SaltLength, // In *bits*
    unsigned int Iterations,
    unsigned int dkLenBits,  // In *bits*
    FREEOTFEBYTE* DK
)
{
    BOOL retval = FALSE;
    DIOC_DERIVE_KEY_IN* DIOCIn;
    DIOC_DERIVE_KEY_OUT* DIOCOut;
    DWORD DIOCInSize;
    DWORD DIOCOutSize;
    unsigned int passLen;  // In bytes

    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("driver_DeriveKey\n")));

    passLen = strlen(Password);

    DIOCInSize = (
                  (
                   sizeof(*DIOCIn) - 
                   sizeof(DIOCIn->Password)
                  ) - 
                  sizeof(DIOCIn->Salt)
                 ) + 
                 passLen +
                 (SaltLength / 8);

    // We use the maximum buffer possible, as the full MAC length depends on
    // the MAC, hash, etc
    DIOCOutSize = sizeof(*DIOCOut) -
                  sizeof(DIOCOut->DerivedKey) +
                  (max(MAX_DERIVED_KEY_LENGTH, dkLenBits) / 8);

    DIOCIn = malloc(DIOCInSize);
    DIOCOut = malloc(DIOCOutSize);


    if (
        (DIOCIn != NULL) &&
        (DIOCOut != NULL) 
       ) 
        {
        DIOCIn->KDFAlgorithm = kdfAlgorithm;
        wcscpy(DIOCIn->HashDeviceName, hashKernelModeDeviceName);
        DIOCIn->HashGUID = hashGUID;
        wcscpy(DIOCIn->CypherDeviceName, cypherKernelModeDeviceName);
        DIOCIn->CypherGUID = cypherGUID;
        DIOCIn->Iterations = Iterations;
        DIOCIn->LengthWanted = dkLenBits;
        DIOCIn->PasswordLength = (passLen * 8);
        DIOCIn->SaltLength = SaltLength;
        memcpy(DIOCIn->Password, Password, passLen);
        memcpy((DIOCIn->Password + passLen), Salt, (SaltLength / 8));

        if (mainDriver->FnDeriveKey(
                                    DIOCInSize,
                                    DIOCIn,
                                    DIOCOutSize,
                                    DIOCOut
                                   ) == ERROR_SUCCESS)
            {
            if (DIOCOut->DerivedKeyLength >= dkLenBits)
                {                
                memcpy(DK, DIOCOut->DerivedKey, (dkLenBits / 8));
                retval = TRUE;
                }
            }
        }

    SecZeroAndFreeMemory(DIOCIn, DIOCInSize);
    SecZeroAndFreeMemory(DIOCOut, DIOCOutSize);

    DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("driver_DeriveKey\n")));
    return retval;
}


// =========================================================================
// Generate MAC of data using hash driver/encryption driver identified
// Note: "tBits" is in *bits* not *bytes*
// tBits - Set the the number of bits to return; set to -ve value for no
//         truncation/padding
//         If tBits is larger than the number of bits the MAC would normally
//         be, then the MAC will be right-padded with NULLs
//         If tBits is set to a -ve number, then this function will return
//         an MAC of variable length
//         This will be set to the length of MACOut on exit
// MACOut - This will be set to point to the MAC generated. This function
//          allocates memory for the MAC; it is is *callers* responsibility to
//          free this off after use
BOOL driver_MACData(
    MODULE_DETAILS_MAIN* mainDriver,

    MAC_ALGORITHM macAlgorithm,
    const WCHAR* hashKernelModeDeviceName,
    GUID hashGUID,
    const WCHAR* cypherKernelModeDeviceName,
    GUID cypherGUID,
    unsigned int KeyLength,
    FREEOTFEBYTE* Key,
    unsigned int DataLength,
    FREEOTFEBYTE* Data,
    FREEOTFEBYTE** MACOut,
    int* tBits
)
{
    BOOL retval = FALSE;
    DIOC_GENERATE_MAC_IN* DIOCIn;
    DIOC_GENERATE_MAC_OUT* DIOCOut;
    DWORD DIOCInSize;
    DWORD DIOCOutSize;

    DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("driver_MACData\n")));

    DIOCInSize = sizeof(*DIOCIn) - 
                 sizeof(DIOCIn->Key) - 
                 sizeof(DIOCIn->Data) + 
                 (KeyLength / 8) +
                 (DataLength / 8);

    // We use the maximum buffer possible, as the full MAC length depends on
    // the MAC, hash, etc
    DIOCOutSize = (sizeof(*DIOCOut) - sizeof(DIOCOut->MAC)) +
                  (max(MAX_MAC_LENGTH, *tBits) / 8);

    DIOCIn = malloc(DIOCInSize);
    DIOCOut = malloc(DIOCOutSize);

    if (
        (DIOCIn != NULL) &&
        (DIOCOut != NULL) 
       ) 
        {
        DIOCIn->MACAlgorithm = macAlgorithm;
        wcscpy(DIOCIn->HashDeviceName, hashKernelModeDeviceName);
        DIOCIn->HashGUID = hashGUID;
        wcscpy(DIOCIn->CypherDeviceName, cypherKernelModeDeviceName);
        DIOCIn->CypherGUID = cypherGUID;
        DIOCIn->LengthWanted = *tBits;
        DIOCIn->KeyLength = KeyLength;
        DIOCIn->DataLength = DataLength;
        memcpy(DIOCIn->Key, Key, (KeyLength / 8));
        memcpy((DIOCIn->Key + (KeyLength / 8)), Data, (DataLength / 8));

        if (mainDriver->FnMACData(
                                  DIOCInSize,
                                  DIOCIn,
                                  DIOCOutSize,
                                  DIOCOut

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -