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

📄 randlib.c

📁 windows的加密api源码
💻 C
📖 第 1 页 / 共 3 页
字号:
                &dwBytesThisPass
                )) {

            return FALSE;
        }

        dwFilledBytes += dwBytesThisPass;
    }

    return TRUE;
}


BOOL
RandomFillBuffer(
        OUT BYTE *pbBuffer,
    IN      DWORD *pdwLength
    )
{
    unsigned int RC4BytesUsed;
    unsigned int KeyId;

#ifdef KMODE_RNG
    PAGED_CODE();
#endif  // KMODE_RNG


    //
    // update circular hash with user supplied bits.
    //

    if(!UpdateCircularHash( &g_CircularHashCtx, pbBuffer, *pdwLength ))
        return FALSE;


    //
    // select key.
    //

    rc4_safe_select( g_RC4SafeCtx, &KeyId, &RC4BytesUsed );


    //
    // check if re-key required.
    //

    if ( RC4BytesUsed >= g_dwRC4RekeyParam )
    {
        PBYTE       pbCircularHash;
        DWORD       cbCircularHash;
        BYTE        pbRandomKey[ 256 ];
        DWORD       cbRandomKey = sizeof(pbRandomKey);

        RC4BytesUsed = g_dwRC4RekeyParam;

        if(!GetCircularHashValue(
                &g_CircularHashCtx,
                &pbCircularHash,
                &cbCircularHash
                )) {

            return FALSE;
        }

        if(!GatherRandomKey( pbCircularHash, cbCircularHash, pbRandomKey, &cbRandomKey ))
            return FALSE;

        //
        // Create RC4 key
        //

        rc4_safe_key(
                g_RC4SafeCtx,
                KeyId,
                cbRandomKey,
                pbRandomKey
                );

        ZeroMemory( pbRandomKey, sizeof(pbRandomKey) );
    }


    //
    // only use RC4_REKEY_PARAM bytes from each RC4 key
    //

    {
        DWORD dwMaxPossibleBytes = g_dwRC4RekeyParam - RC4BytesUsed;

        if (*pdwLength > dwMaxPossibleBytes)
            *pdwLength = dwMaxPossibleBytes;
    }

    rc4_safe( g_RC4SafeCtx, KeyId, *pdwLength, pbBuffer );

    return TRUE;
}


#ifdef KMODE_RNG
#ifdef USE_HW_RNG
#ifdef _M_IX86
#define NUM_HW_DWORDS_TO_GATHER     4
#define INTEL_DRIVER_NAME           L"\\Device\\ISECDRV"

unsigned int
QueryForHWRandomBits(
    IN      DWORD *pdwRandom,
    IN  OUT DWORD cdwRandom
    )
{
    UNICODE_STRING ObjectName;
    IO_STATUS_BLOCK StatusBlock;
    KEVENT Event;
    PIRP pIrp = NULL;
  	ISD_Capability ISD_Cap;                //in/out for GetCapability
	ISD_RandomNumber ISD_Random;           //in/out for GetRandomNumber
    PDEVICE_OBJECT pDeviceObject = NULL;
    DWORD i = 0;
    unsigned int Status = ERROR_SUCCESS;

    PAGED_CODE();

    if (1 == g_dwHWDriver)
    {
        Status = STATUS_ACCESS_DENIED;
        goto Ret;
    }

    ZeroMemory( &ObjectName, sizeof(ObjectName) );
    ZeroMemory( &StatusBlock, sizeof(StatusBlock) );
    ZeroMemory(&ISD_Cap, sizeof(ISD_Cap));


    if (NULL == g_pDeviceObject)
    {
        ObjectName.Length = sizeof(INTEL_DRIVER_NAME) - sizeof(WCHAR);
        ObjectName.MaximumLength = sizeof(INTEL_DRIVER_NAME);
        ObjectName.Buffer = INTEL_DRIVER_NAME;
        Status = IoGetDeviceObjectPointer(&ObjectName,
                                          FILE_ALL_ACCESS,
                                          &g_pFileObject,
                                          &pDeviceObject);

        if ( !NT_SUCCESS(Status) )
        {
            g_dwHWDriver = 1;
            goto Ret;
        }

        if (NULL == g_pDeviceObject)
        {
            InterlockedExchangePointer(&g_pDeviceObject, pDeviceObject);
        }
    }

    //
    // If this fails then it is because there is no such device
    // which signals completion.
    //


    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    ISD_Cap.uiIndex = ISD_RNG_ENABLED;  //Set input member
    pIrp = IoBuildDeviceIoControlRequest(
        IOCTL_ISD_GetCapability,
        g_pDeviceObject,
        &ISD_Cap,
        sizeof(ISD_Cap),
        &ISD_Cap,
        sizeof(ISD_Cap),
        FALSE,
        &Event,
        &StatusBlock); 

    if (pIrp == NULL) {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Ret;
    }

    Status = IoCallDriver(g_pDeviceObject, pIrp);

    if (Status == STATUS_PENDING) {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        Status = StatusBlock.Status;
    }

    if (ISD_Cap.iStatus != ISD_EOK) {  
        Status = STATUS_NOT_IMPLEMENTED;
        goto Ret;
    }

    // now get the random bits
    for (i = 0; i < cdwRandom; i++) {
        ZeroMemory(&ISD_Random, sizeof(ISD_Random));
        KeInitializeEvent(&Event, NotificationEvent, FALSE);

        pIrp = IoBuildDeviceIoControlRequest(
            IOCTL_ISD_GetRandomNumber,
            g_pDeviceObject,
            &ISD_Random,
            sizeof(ISD_Random),
            &ISD_Random,
            sizeof(ISD_Random),
            FALSE,
            &Event,
            &StatusBlock); 

        if (pIrp == NULL) {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto Ret;
        }

        Status = IoCallDriver(g_pDeviceObject, pIrp);

        if (Status == STATUS_PENDING) {
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
            Status = StatusBlock.Status;
        }    

        if (ISD_Random.iStatus != ISD_EOK) {
            Status = STATUS_NOT_IMPLEMENTED;
            goto Ret;
        }

        pdwRandom[i] = pdwRandom[i] ^ ISD_Random.uiRandomNum;
    }
Ret:
    return Status;
}
#endif // _M_IX86
#endif // USE_HW_RNG
#endif // KMODE_RNG

BOOL
GatherRandomKey(
    IN      BYTE            *pbUserSeed,
    IN      DWORD           cbUserSeed,
    IN  OUT BYTE            *pbRandomKey,
    IN  OUT DWORD           *pcbRandomKey
    )
{

    LPBYTE  pbWorkingBuffer = NULL;
    DWORD   cbWorkingBuffer;
    DWORD   cbBufferRemaining;
    BYTE    *pbCurrentBuffer;
    DWORD   *pdwTmp;
    BOOL    fRet;

#ifdef KMODE_RNG
    PAGED_CODE();
#endif  // KMODE_RNG




    //
    // in NT Usermode, try to re-seed by calling the Kernelmode RNG.
    //

#ifndef KMODE_RNG
    if( GatherRandomKeyFastUserMode( pbUserSeed, cbUserSeed, pbRandomKey, pcbRandomKey ))
        return TRUE;
#endif



//
// verify current working buffer has space for candidate data.
//

#define VERIFY_BUFFER( size ) {                                         \
    if( cbBufferRemaining < size )                                      \
        goto finished;                                                  \
    }

//
// update working buffer and increment to next QWORD aligned boundary.
//

#define UPDATE_BUFFER( size ) {                                         \
    DWORD dwSizeRounded;                                                \
    dwSizeRounded = (size + sizeof(ULONG64)) & ~(sizeof(ULONG64)-1);    \
    if(dwSizeRounded > cbBufferRemaining)                               \
        goto finished;                                                  \
    pbCurrentBuffer += dwSizeRounded;                                   \
    cbBufferRemaining -= dwSizeRounded;                                 \
    }


    cbWorkingBuffer = 3584;
    pbWorkingBuffer = (PBYTE)ALLOC( cbWorkingBuffer );
    if( pbWorkingBuffer == NULL ) {
        return FALSE;
    }

    cbBufferRemaining = cbWorkingBuffer;
    pbCurrentBuffer = pbWorkingBuffer;

    //
    // pickup user supplied bits.
    //

    VERIFY_BUFFER( cbUserSeed );
    CopyMemory( pbCurrentBuffer, pbUserSeed, cbUserSeed );
    UPDATE_BUFFER( cbUserSeed );

    //
    // ** indicates US DoD's specific recommendations for password generation
    //


    //
    // process id
    //

    pdwTmp = (PDWORD)pbCurrentBuffer;

#ifndef KMODE_RNG
    *pdwTmp = GetCurrentProcessId();
#else
///    *pdwTmp = PsGetCurrentProcessId();
#endif

    UPDATE_BUFFER( sizeof(DWORD) );

    //
    // thread id
    //

    pdwTmp = (PDWORD)pbCurrentBuffer;

#ifndef KMODE_RNG
    *pdwTmp = GetCurrentThreadId();
#else
///    *pdwTmp = PsGetCurrentThreadId();
#endif

    UPDATE_BUFFER( sizeof(DWORD) );


    //
    // ** ticks since boot (system clock)
    //

    pdwTmp = (PDWORD)pbCurrentBuffer;

#ifndef KMODE_RNG
    *pdwTmp = GetTickCount();
#else
///    *pdwTmp = NtGetTickCount();
#endif  // !KMODE_RNG

    UPDATE_BUFFER( sizeof(DWORD) );


    //
    // ** system time, in ms, sec, min (date & time)
    //

#ifndef KMODE_RNG
    {
        PSYSTEMTIME psysTime = (PSYSTEMTIME)pbCurrentBuffer;

        VERIFY_BUFFER( sizeof( *psysTime ) );
        GetLocalTime(psysTime);
        UPDATE_BUFFER( sizeof( *psysTime ) );
    }
#else
    {

        PSYSTEM_TIMEOFDAY_INFORMATION pTimeOfDay;
        ULONG cbSystemInfo;

        pTimeOfDay = (PSYSTEM_TIMEOFDAY_INFORMATION)pbCurrentBuffer;

        VERIFY_BUFFER( sizeof(*pTimeOfDay) );

        _NtQuerySystemInformation(
                    SystemTimeOfDayInformation,
                    pTimeOfDay,
                    sizeof(*pTimeOfDay),
                    &cbSystemInfo
                    );

        UPDATE_BUFFER(  cbSystemInfo );
    }

#endif  // !KMODE_RNG

    //
    // ** hi-res performance counter (system counters)
    //

    {
        LARGE_INTEGER   *pliPerfCount = (PLARGE_INTEGER)pbCurrentBuffer;

        VERIFY_BUFFER( sizeof(*pliPerfCount) );

#ifndef KMODE_RNG
        QueryPerformanceCounter(pliPerfCount);
#else
///        ZwQueryPerformanceCounter(pliPerfCount, &liPerfFreq);
#endif  // !KMODE_RNG

        UPDATE_BUFFER( sizeof(*pliPerfCount) );
    }

#ifndef KMODE_RNG

    //
    // memory status
    //

    {
        MEMORYSTATUS *pmstMemStat = (MEMORYSTATUS *)pbCurrentBuffer;

        VERIFY_BUFFER( sizeof(*pmstMemStat) );

        pmstMemStat->dwLength = sizeof(MEMORYSTATUS);
        GlobalMemoryStatus( pmstMemStat );

        UPDATE_BUFFER( sizeof(*pmstMemStat) );
    }

#endif  // !KMODE_RNG


    //
    // free disk clusters
    //

#ifndef KMODE_RNG

    {
        PDWORD pdwDiskInfo = (PDWORD)pbCurrentBuffer;

        VERIFY_BUFFER( (sizeof(DWORD) * 4) );

        GetDiskFreeSpace(
                    NULL,
                    &pdwDiskInfo[0],    // sectors per cluster
                    &pdwDiskInfo[1],    // bytes per sector
                    &pdwDiskInfo[2],    // number of free clusters
                    &pdwDiskInfo[3]     // total number of clusters
                    );

        UPDATE_BUFFER( (sizeof(DWORD) * 4) );
    }
#endif  // !KMODE_RNG


#ifndef KMODE_RNG
    {

#if 0
        //
        // hash the entire user environment block.
        // we do this instead of GetUserName & GetComputerName,
        // as the environment block contains these values, plus additional
        // values.
        //

        static BOOL fHashedEnv;
        static BYTE HashEnv[ MD4_LEN ];

        if( !fHashedEnv ) {

            LPVOID lpEnvBlock;
            BOOL fAnsi = FALSE;

            //
            // try the Unicode version first, as, on WinNT, this returns us
            // a pointer to the existing Unicode environment block, rather
            // than an allocated copy.  Fallback to ANSI if this fails (eg: Win9x)
            //

            lpEnvBlock = GetEnvironmentStringsW();
            if( lpEnvBlock == NULL )
            {
                lpEnvBlock = GetEnvironmentStringsA();
                fAnsi = TRUE;
            }


            if( lpEnvBlock != NULL ) {

                ULONG cbEntry;
                PBYTE pbEntry;
                MD4_CTX MD4Ctx;


                MD4Init( &MD4Ctx );

                pbEntry = (PBYTE)lpEnvBlock;
                cbEntry = 0;

                do {

                    if( !fAnsi ) {
                        pbEntry += (cbEntry + sizeof(WCHAR));
                        cbEntry = lstrlenW( (LPWSTR)pbEntry ) * sizeof(WCHAR);
                    } else {
                        pbEntry += (cbEntry + sizeof(CHAR));
                        cbEntry = lstrlenA( (LPSTR)pbEntry ) * sizeof(CHAR);
                    }

                    MD4Update(
                        &MD4Ctx,
                        (unsigned char *)pbEntry,
                        (unsigned int)cbEntry

⌨️ 快捷键说明

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