#define FUSION_PROFILING 1 #define DBG 1 #include "windows.h" #include "wincrypt.h" #include "stdlib.h" #include "stdio.h" #include "fastsha1.h" #include "fusionbuffer.h" #include "perfclocking.h" FASTSHA1_STATE ShaState; #define ASM_CPUID { __asm cpuid } #define ASM_RDTSC { __asm rdtsc } #define NUMBER_OF( n ) ( sizeof(n) / sizeof(*n) ) #define INPUT_BLOCK_SIZE ( 4096*4 ) inline VOID GetCpuIdLag( LARGE_INTEGER *ref ) { LARGE_INTEGER temp, temp2; #if !defined(_WIN64) _asm { cpuid cpuid cpuid cpuid cpuid rdtsc mov temp.LowPart, eax mov temp.HighPart, edx cpuid rdtsc mov temp2.LowPart, eax mov temp2.HighPart, edx } ref->QuadPart = temp2.QuadPart - temp.QuadPart; #else ref->QuadPart = 0; #endif } LARGE_INTEGER CpuIdLag; BYTE TestCase1[] = { 0x61, 0x62, 0x63 }; BYTE TestCase2[] = { 0x61, 0x62, 0x63, 0x64, 0x62, 0x63, 0x64, 0x65, 0x63, 0x64, 0x65, 0x66, 0x64, 0x65, 0x66, 0x67, 0x65, 0x66, 0x67, 0x68, 0x66, 0x67, 0x68, 0x69, 0x67, 0x68, 0x69, 0x6A, 0x68, 0x69, 0x6A, 0x6B, 0x69, 0x6A, 0x6B, 0x6C, 0x6A, 0x6B, 0x6C, 0x6D, 0x6B, 0x6C, 0x6D, 0x6E, 0x6C, 0x6D, 0x6E, 0x6F, 0x6D, 0x6E, 0x6F, 0x70, 0x6E, 0x6F, 0x70, 0x71 }; HCRYPTPROV hProvider; #define CHECKFAIL( f ) do { if ( !(f) ) return FALSE; } while ( 0 ) BOOL ObtainFastSHA1OfFile( PBYTE pvBase, SIZE_T cbSize, BYTE bShaHashData[20], PSIZE_T pcbSize ) { FUSION_PERF_INFO InfoSlots[4]; FASTSHA1_STATE State; State.cbStruct = sizeof( State ); PERFINFOTIME( &InfoSlots[0], CHECKFAIL( InitializeFastSHA1State( 0, &State ) ) ); while ( cbSize ) { DWORD dwThisSize = ( cbSize > INPUT_BLOCK_SIZE ) ? INPUT_BLOCK_SIZE : cbSize; PERFINFOTIME( &InfoSlots[1], CHECKFAIL( HashMoreFastSHA1Data( &State, pvBase, dwThisSize ) ) ); pvBase += dwThisSize; cbSize -= dwThisSize; } PERFINFOTIME( &InfoSlots[2], CHECKFAIL( FinalizeFastSHA1State( 0, &State ) ) ); PERFINFOTIME( &InfoSlots[3], CHECKFAIL( GetFastSHA1Result( &State, bShaHashData, pcbSize ) ) ); FusionpReportPerfInfo( FUSIONPERF_DUMP_TO_STDOUT | FUSIONPERF_DUMP_ALL_STATISTICS | FUSIONPERF_DUMP_ALL_SOURCEINFO, InfoSlots, NUMBER_OF( InfoSlots ) ); printf("\n\n"); return TRUE; } BOOL ObtainReferenceSHA1Hash( PBYTE pvBase, SIZE_T cbSize, BYTE bShaHashData[20], PDWORD pdwData ) { FUSION_PERF_INFO InfoSlots[4]; FASTSHA1_STATE State; DWORD dwDump; HCRYPTHASH hHash; PERFINFOTIME( &InfoSlots[0], CHECKFAIL( CryptCreateHash( hProvider, CALG_SHA1, NULL, 0, &hHash ) ) ); while ( cbSize ) { DWORD dwThisSize = ( cbSize > INPUT_BLOCK_SIZE ) ? INPUT_BLOCK_SIZE : cbSize; PERFINFOTIME( &InfoSlots[1], CHECKFAIL( CryptHashData( hHash, pvBase, dwThisSize, 0 ) ) ); cbSize -= dwThisSize; pvBase += dwThisSize; } PERFINFOTIME( &InfoSlots[2], CHECKFAIL( CryptGetHashParam( hHash, HP_HASHVAL, bShaHashData, pdwData, 0 ) ) ); PERFINFOTIME( &InfoSlots[3], CHECKFAIL( CryptDestroyHash( hHash ) ) ); FusionpReportPerfInfo( FUSIONPERF_DUMP_TO_STDOUT | FUSIONPERF_DUMP_ALL_STATISTICS | FUSIONPERF_DUMP_ALL_SOURCEINFO, InfoSlots, NUMBER_OF( InfoSlots ) ); printf("\n\n"); return TRUE; } extern "C" int __cdecl wmain(int argc, wchar_t** argv) { BYTE bDestination[20]; SIZE_T cbDestination; int i = 0; ShaState.cbStruct = sizeof( ShaState ); InitializeFastSHA1State( 0, &ShaState ); HashMoreFastSHA1Data( &ShaState, TestCase1, sizeof( TestCase1 ) ); FinalizeFastSHA1State( 0, &ShaState ); GetCpuIdLag( &CpuIdLag ); CryptAcquireContextW( &hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_SILENT | CRYPT_VERIFYCONTEXT ); BYTE bReferenceHash[20], bFastHash[20]; SIZE_T cbReferenceHash, cbFastHash; HANDLE hFile, hFileMapping; PBYTE pbFileContents; DWORD dwFileContents; if ( GetFileAttributesW( argv[1] ) & FILE_ATTRIBUTE_DIRECTORY ) { printf( "dir : %ls\n", argv[1] ); return 0; } hFile = CreateFileW( argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( hFile == INVALID_HANDLE_VALUE ) goto ErrorPath; hFileMapping = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL ); if ( ( hFileMapping == NULL ) || ( hFileMapping == INVALID_HANDLE_VALUE ) ) goto ErrorPath; pbFileContents = (PBYTE)MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, 0 ); if ( pbFileContents == NULL ) goto ErrorPath; dwFileContents = GetFileSize( hFile, NULL ); if ( !ObtainReferenceSHA1Hash( pbFileContents, dwFileContents, bReferenceHash, &(cbReferenceHash = sizeof(bReferenceHash)) ) ) { printf("(Reference failed) "); goto ErrorPath; } if ( !ObtainFastSHA1OfFile( pbFileContents, dwFileContents, bFastHash, &(cbFastHash = sizeof(bFastHash)) ) ) { printf( "(fastsha1 failed) " ); goto ErrorPath; } if ( memcmp( bFastHash, bReferenceHash, 20 ) == 0 ) { printf( "match: %ls\n", argv[1] ); } else { printf( "fails: %ls\n", argv[1] ); } CryptReleaseContext( hProvider, 0 ); return 0; ErrorPath: printf( "Failure: 0x%08x on file %ls\n", GetLastError(), argv[1] ); return 1; }