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

📄 freeotfe4pdacypherdriver.c

📁 文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2, MD4, MD5, RIPEMD-128, RIPEMD-160, SHA-1, SHA-224, SHA-256,
💻 C
📖 第 1 页 / 共 2 页
字号:
// 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 + -