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

📄 randlib.c

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

                } while( cbEntry );


                MD4Final( &MD4Ctx );

                CopyMemory( HashEnv, MD4Ctx.digest, sizeof(HashEnv) );

                if( !fAnsi ) {
                    FreeEnvironmentStringsW( lpEnvBlock );
                } else {
                    FreeEnvironmentStringsA( lpEnvBlock );
                }
            }

            //
            // only try this once.  if it failed once, it will likely never
            // succeed.
            //

            fHashedEnv = TRUE;
        }


        VERIFY_BUFFER( (sizeof(HashEnv)) );
        CopyMemory( pbCurrentBuffer, HashEnv, sizeof(HashEnv) );
        UPDATE_BUFFER( (sizeof(HashEnv)) );

#else
        static DWORD dwComputerNameSize;
        static DWORD dwUserNameSize;
        static CHAR lpComputerName [MAX_COMPUTERNAME_LENGTH + 1];
        static CHAR lpUserName [UNLEN + 1];

        //
        // note use of two temp DWORDs - that's to keep the static DWORDs
        // thread safe
        //

        //
        // **SystemID
        //

        if(dwComputerNameSize == 0) {
            DWORD dwTempComputerNameSize = sizeof(lpComputerName) / sizeof(CHAR);

            if(GetComputerNameA(lpComputerName, &dwTempComputerNameSize))
                dwComputerNameSize = dwTempComputerNameSize;
        }

        if(dwComputerNameSize != 0) {
            // dwComputerNameSize = len not including null termination

            VERIFY_BUFFER( dwComputerNameSize );
            CopyMemory( pbCurrentBuffer, lpComputerName, dwComputerNameSize );
            UPDATE_BUFFER( dwComputerNameSize );
        }

        //
        // **UserID
        //

        if(dwUserNameSize == 0) {
            DWORD dwTempUserNameSize = sizeof(lpUserName) / sizeof(CHAR);

            if(GetUserNameA(lpUserName, &dwTempUserNameSize)) {
                // dwUserNameSize = len including null termination
                dwUserNameSize = dwTempUserNameSize - 1;
            }
        }

        if(dwUserNameSize != 0) {
            VERIFY_BUFFER( dwUserNameSize );
            CopyMemory( pbCurrentBuffer, lpUserName, dwUserNameSize );
            UPDATE_BUFFER( dwUserNameSize );
        }
#endif
    }
#endif  // !KMODE_RNG

    //
    // this code path has been moved to the end so that our CombineRand()
    // operation on NT mixes in with everything slammed into the
    // rand context buffer.
    //

#ifndef KMODE_RNG
    if(!IsRNGWinNT()) {

        //
        // only user info if we are not running on NT.
        // this prevents deadlocks on WinNT when the RNG is called from CSRSS
        //

        POINT   *ppoint;
        LONG    *plTime;

        //
        // cursor position
        //

        ppoint = (POINT*)pbCurrentBuffer;

        VERIFY_BUFFER( sizeof(*ppoint) );
        _GetCursorPos(ppoint);
        UPDATE_BUFFER( sizeof(*ppoint) );

        //
        // last messages' timestamp
        //

        plTime = (LONG*)pbCurrentBuffer;

        VERIFY_BUFFER( sizeof(*plTime) );
        *plTime = _GetMessageTime();
        UPDATE_BUFFER( sizeof(*plTime) );


    } else
#endif  // !KMODE_RNG
    {
        unsigned char *pbCounterState = (unsigned char*)pbCurrentBuffer;
        unsigned long cbCounterState = 64;

        VERIFY_BUFFER(cbCounterState);

        if(GatherCPUSpecificCounters( pbCounterState, &cbCounterState )) {
            UPDATE_BUFFER( cbCounterState );
        }


        //
        // call NtQuerySystemInformation on NT if available.
        //

        if( (void*)_NtQuerySystemInformation ) {

            PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION pSystemProcessorPerformanceInfo;
            PSYSTEM_PERFORMANCE_INFORMATION pSystemPerformanceInfo;
            PSYSTEM_EXCEPTION_INFORMATION pSystemExceptionInfo;
            PSYSTEM_LOOKASIDE_INFORMATION pSystemLookasideInfo;
            PSYSTEM_INTERRUPT_INFORMATION pSystemInterruptInfo;
            PSYSTEM_PROCESS_INFORMATION pSystemProcessInfo;
            ULONG cbSystemInfo;
            NTSTATUS Status;

            //
            // fixed length system info calls.
            //

            pSystemProcessorPerformanceInfo = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)pbCurrentBuffer;

            VERIFY_BUFFER( sizeof(*pSystemProcessorPerformanceInfo) );

            Status = _NtQuerySystemInformation(
                        SystemProcessorPerformanceInformation,
                        pSystemProcessorPerformanceInfo,
                        sizeof(*pSystemProcessorPerformanceInfo),
                        &cbSystemInfo
                        );

            if ( NT_SUCCESS(Status) ) {
                UPDATE_BUFFER( cbSystemInfo );
            }

            pSystemPerformanceInfo = (PSYSTEM_PERFORMANCE_INFORMATION)pbCurrentBuffer;

            VERIFY_BUFFER( sizeof(*pSystemPerformanceInfo) );

            Status = _NtQuerySystemInformation(
                        SystemPerformanceInformation,
                        pSystemPerformanceInfo,
                        sizeof(*pSystemPerformanceInfo),
                        &cbSystemInfo
                        );

            if ( NT_SUCCESS(Status) ) {
                UPDATE_BUFFER(  cbSystemInfo );
            }

            pSystemExceptionInfo = (PSYSTEM_EXCEPTION_INFORMATION)pbCurrentBuffer;

            VERIFY_BUFFER( sizeof(*pSystemExceptionInfo) );

            Status = _NtQuerySystemInformation(
                        SystemExceptionInformation,
                        pSystemExceptionInfo,
                        sizeof(*pSystemExceptionInfo),
                        &cbSystemInfo
                        );

            if ( NT_SUCCESS(Status) ) {
                UPDATE_BUFFER( cbSystemInfo );
            }

            pSystemLookasideInfo = (PSYSTEM_LOOKASIDE_INFORMATION)pbCurrentBuffer;

            VERIFY_BUFFER( sizeof(*pSystemLookasideInfo) );

            Status = _NtQuerySystemInformation(
                        SystemLookasideInformation,
                        pSystemLookasideInfo,
                        sizeof(*pSystemLookasideInfo),
                        &cbSystemInfo
                        );

            if ( NT_SUCCESS(Status) ) {
                UPDATE_BUFFER( cbSystemInfo );
            }

            //
            // variable length system info calls.
            //

            pSystemInterruptInfo = (PSYSTEM_INTERRUPT_INFORMATION)pbCurrentBuffer;
            cbSystemInfo = cbBufferRemaining;

            Status = _NtQuerySystemInformation(
                        SystemInterruptInformation,
                        pSystemInterruptInfo,
                        cbSystemInfo,
                        &cbSystemInfo
                        );

            if ( NT_SUCCESS(Status) ) {
                UPDATE_BUFFER( cbSystemInfo );
            }

            pSystemProcessInfo = (PSYSTEM_PROCESS_INFORMATION)pbCurrentBuffer;
            cbSystemInfo = cbBufferRemaining;

            Status = _NtQuerySystemInformation(
                        SystemProcessInformation,
                        pSystemProcessInfo,
                        cbSystemInfo,
                        &cbSystemInfo
                        );

            if ( NT_SUCCESS(Status) ) {
                UPDATE_BUFFER( cbSystemInfo );
            }

        } // _NtQuerySystemInformation
    }

#ifdef KMODE_RNG
#ifdef USE_HW_RNG
#ifdef _M_IX86
    // attempt to get bits from the INTEL HW RNG
    {
        DWORD rgdwHWRandom[NUM_HW_DWORDS_TO_GATHER];
        NTSTATUS Status;


        VERIFY_BUFFER( sizeof(rgdwHWRandom) );

        Status = QueryForHWRandomBits(
                    rgdwHWRandom,
                    NUM_HW_DWORDS_TO_GATHER
                    );

        if ( NT_SUCCESS(Status) ) {
            UPDATE_BUFFER( sizeof(rgdwHWRandom) );
        }

    }
#endif // _M_IX86
#endif // USE_HW_RNG
#endif // KMODE_RNG

finished:

    {
        RC4_KEYSTRUCT rc4Key;
        BYTE NewSeed[ sizeof(g_VeryLargeHash) ];
        BYTE LocalHash[ sizeof( g_VeryLargeHash ) ];
        DWORD cbBufferSize;

        CopyMemory( LocalHash, g_VeryLargeHash, sizeof(g_VeryLargeHash) );

        rc4_key( &rc4Key, sizeof(LocalHash), LocalHash );

        cbBufferSize = cbWorkingBuffer - cbBufferRemaining;
        if( cbBufferSize > cbWorkingBuffer )
            cbBufferSize = cbWorkingBuffer;

        fRet = VeryLargeHashUpdate(
                    pbWorkingBuffer,                    // buffer to hash
                    cbBufferSize,
                    LocalHash
                    );

        CopyMemory( NewSeed, LocalHash, sizeof(LocalHash) );
        CopyMemory( g_VeryLargeHash, LocalHash, sizeof(LocalHash) );
        rc4( &rc4Key, sizeof( NewSeed ), NewSeed );

        //
        // write seed out.
        //

        WriteSeed( NewSeed, sizeof(NewSeed) );

        rc4_key( &rc4Key, sizeof(LocalHash), LocalHash );
        rc4( &rc4Key, *pcbRandomKey, pbRandomKey );

        ZeroMemory( &rc4Key, sizeof(rc4Key) );

        if( pbWorkingBuffer ) {
            FREE( pbWorkingBuffer );
        }
    }


    return fRet;
}



#ifndef KMODE_RNG

BOOL
GatherRandomKeyFastUserMode(
    IN      BYTE            *pbUserSeed,
    IN      DWORD           cbUserSeed,
    IN  OUT BYTE            *pbRandomKey,
    IN  OUT DWORD           *pcbRandomKey
    )
/*++

    This routine attempts to gather RNG re-seed material for usermode callers
    from the Kernel mode version of the RNG.  This is accomplished by making
    a device IOCTL into the ksecdd.sys device driver.

--*/
{
    HANDLE hFile;
    NTSTATUS Status;

    if(!IsRNGWinNT())
        return FALSE;

    hFile = g_hKsecDD;

    if( hFile == NULL ) {

        UNICODE_STRING DriverName;
        OBJECT_ATTRIBUTES ObjA;
        IO_STATUS_BLOCK IOSB;
        HANDLE hPreviousValue;

        //
        // call via the ksecdd.sys device driver to get the random bits.
        //

        if( _NtOpenFile == NULL || _RtlInitUnicodeString == NULL ) {
            return FALSE;
        }

        //
        // have to use the Nt flavor of the file open call because it's a base
        // device not aliased to \DosDevices
        //

        _RtlInitUnicodeString( &DriverName, DD_KSEC_DEVICE_NAME_U );
        InitializeObjectAttributes(
                    &ObjA,
                    &DriverName,
                    OBJ_CASE_INSENSITIVE,
                    0,
                    0
                    );

        Status = _NtOpenFile(
                    &hFile,
                    SYNCHRONIZE | FILE_READ_DATA,
                    &ObjA,
                    &IOSB,
                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                    FILE_SYNCHRONOUS_IO_ALERT
                    );


        if( !NT_SUCCESS(Status) )
            return FALSE;

        hPreviousValue = INTERLOCKEDCOMPAREEXCHANGEPOINTER(
                                        &g_hKsecDD,
                                        hFile,
                                        NULL
                                        );

        if( hPreviousValue != NULL ) {

            //
            // race condition, set current value to previously initialized version.
            //

            CloseHandle( hFile );
            hFile = hPreviousValue;
        }
    }

    return DeviceIoControl(
                hFile,
                IOCTL_KSEC_RNG_REKEY,   // indicate a RNG rekey
                pbUserSeed,             // input buffer (existing material)
                cbUserSeed,             // input buffer size
                pbRandomKey,            // output buffer
                *pcbRandomKey,          // output buffer size
                pcbRandomKey,           // bytes written to output buffer
                NULL
                );
}


BOOL
IsRNGWinNT(
    VOID
    )
/*++

    This function determines if we are running on Windows NT and furthermore,
    if it is appropriate to make use of certain user operations where the
    code is running.

    If the function returns TRUE, the caller cannot make calls to user
    based function and should use an alternative approach such as
    NtQuerySystemInformation.

    If the function returns FALSE, the caller can safely call user based
    functions to gather random material.

--*/
{
    static BOOL fIKnow = FALSE;

    // we assume WinNT in case of error.
    static BOOL fIsWinNT = TRUE;

    OSVERSIONINFO osVer;

    if(fIKnow)
        return(fIsWinNT);

    ZeroMemory(&osVer, sizeof(osVer));
    osVer.dwOSVersionInfoSize = sizeof(osVer);

    if( GetVersionEx(&osVer) ) {
        fIsWinNT = (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT);

        if( fIsWinNT ) {
            //
            // if we're on NT, collect entry point address.
            //
            HMODULE hNTDll = GetModuleHandleW( L"ntdll.dll" );

            if( hNTDll ) {
                _NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(
                                hNTDll,
                                "NtQuerySystemInformation"
                                );

                //
                // On WinNT, adjust the rekey param to be a much larger value
                // because we have more entropy to key from.
                //

                if( _NtQuerySystemInformation )
                    g_dwRC4RekeyParam = RC4_REKEY_PARAM_NT;

                _NtOpenFile = (NTOPENFILE)GetProcAddress(
                                hNTDll,
                                "NtOpenFile"
                                );

                _RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress(
                                hNTDll,
                                "RtlInitUnicodeString"
                                );
            }
        } else {
            //
            // collect entry point addresses for Win95
            //
            HMODULE hUser32 = LoadLibraryA("user32.dll");

            if( hUser32 ) {
                _GetCursorPos = (GETCURSORPOS)GetProcAddress(
                                hUser32,
                                "GetCursorPos"
                                );

                _GetMessageTime = (GETMESSAGETIME)GetProcAddress(
                                hUser32,
                                "GetMessageTime"
                                );
            }

        }
    }

    // even on an error, this is as good as it gets
    fIKnow = TRUE;

    return fIsWinNT;
}

#endif  // !KMODE_RNG

⌨️ 快捷键说明

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