/*++ Copyright (c) 1998 Microsoft Corporation Abstract: Build up a "Very Large Hash" based on arbitrary sized input data of size cbData specified by the pvData buffer. This implementation updates a 640bit hash, which is internally based on multiple invocations of a modified SHA-1 which doesn't implement endian conversion internally. Author: Scott Field (sfield) 24-Sep-98 --*/ #ifndef KMODE_RNG #include #include #include #include #else #include #include #endif // KMODE_RNG #include #include "vlhash.h" #ifdef KMODE_RNG #ifdef ALLOC_PRAGMA #pragma alloc_text(PAGE, VeryLargeHashUpdate) #endif // ALLOC_PRAGMA #endif // KMODE_RNG BOOL VeryLargeHashUpdate( IN VOID *pvData, // data from perfcounters, user supplied, etc. IN DWORD cbData, IN OUT BYTE VeryLargeHash[A_SHA_DIGEST_LEN * 4] ) { // // pointers to 1/4 size chunks of seed pointed to by VeryLargeHash // DWORD cbSeedChunk; PBYTE pSeed1; PBYTE pSeed2; PBYTE pSeed3; PBYTE pSeed4; // // pointers to 1/4 size chunks of data pointed to by pData // DWORD cbDataChunk; PBYTE pData1; PBYTE pData2; PBYTE pData3; PBYTE pData4; // // pointers to individual intermediate hash within IntermediateHashes // PBYTE IHash1; PBYTE IHash2; PBYTE IHash3; PBYTE IHash4; BYTE IntermediateHashes[ A_SHA_DIGEST_LEN * 4 ]; // // pointer to output hash within VeryLargeHash buffer. // PBYTE OutputHash; A_SHA_CTX shaContext; #ifdef KMODE_RNG PAGED_CODE(); #endif // KMODE_RNG // // check parameters // if( VeryLargeHash == NULL || pvData == NULL ) return FALSE; // // break up input blocks into 1/4 size chunks. // cbSeedChunk = A_SHA_DIGEST_LEN; cbDataChunk = cbData / 4; if( cbDataChunk == 0 ) return FALSE; pSeed1 = VeryLargeHash; pSeed2 = pSeed1 + cbSeedChunk; pData1 = (PBYTE)pvData; pData2 = pData1 + cbDataChunk; IHash1 = IntermediateHashes; IHash2 = IHash1 + A_SHA_DIGEST_LEN; // // round 1 // A_SHAInit( &shaContext ); A_SHAUpdateNS( &shaContext, pSeed1, cbSeedChunk ); A_SHAUpdateNS( &shaContext, pData1, cbDataChunk ); A_SHAUpdateNS( &shaContext, pSeed2, cbSeedChunk ); A_SHAUpdateNS( &shaContext, pData2, cbDataChunk ); A_SHAFinalNS( &shaContext, IHash1 ); // // round 2 // A_SHAInit( &shaContext ); A_SHAUpdateNS( &shaContext, pSeed2, cbSeedChunk ); A_SHAUpdateNS( &shaContext, pData2, cbDataChunk ); A_SHAUpdateNS( &shaContext, pSeed1, cbSeedChunk ); A_SHAUpdateNS( &shaContext, pData1, cbDataChunk ); A_SHAFinalNS( &shaContext, IHash2 ); pSeed3 = pSeed2 + cbSeedChunk; pSeed4 = pSeed3 + cbSeedChunk; pData3 = pData2 + cbDataChunk; pData4 = pData3 + cbDataChunk; IHash3 = IHash2 + A_SHA_DIGEST_LEN; IHash4 = IHash3 + A_SHA_DIGEST_LEN; // // round 3 // A_SHAInit( &shaContext ); A_SHAUpdateNS( &shaContext, pSeed3, cbSeedChunk ); A_SHAUpdateNS( &shaContext, pData3, cbDataChunk ); A_SHAUpdateNS( &shaContext, pSeed4, cbSeedChunk ); A_SHAUpdateNS( &shaContext, pData4, cbDataChunk ); A_SHAFinalNS( &shaContext, IHash3 ); // // round 4 // A_SHAInit( &shaContext ); A_SHAUpdateNS( &shaContext, pSeed4, cbSeedChunk ); A_SHAUpdateNS( &shaContext, pData4, cbDataChunk ); A_SHAUpdateNS( &shaContext, pSeed3, cbSeedChunk ); A_SHAUpdateNS( &shaContext, pData3, cbDataChunk ); A_SHAFinalNS( &shaContext, IHash4 ); // // round 5 // OutputHash = VeryLargeHash; A_SHAInit( &shaContext ); A_SHAUpdateNS( &shaContext, IHash1, A_SHA_DIGEST_LEN ); A_SHAUpdateNS( &shaContext, IHash3, A_SHA_DIGEST_LEN ); A_SHAFinalNS( &shaContext, OutputHash ); // // round 6 // OutputHash += A_SHA_DIGEST_LEN; A_SHAInit( &shaContext ); A_SHAUpdateNS( &shaContext, IHash2, A_SHA_DIGEST_LEN ); A_SHAUpdateNS( &shaContext, IHash4, A_SHA_DIGEST_LEN ); A_SHAFinalNS( &shaContext, OutputHash ); // // round 7 // OutputHash += A_SHA_DIGEST_LEN; A_SHAInit( &shaContext ); A_SHAUpdateNS( &shaContext, IHash3, A_SHA_DIGEST_LEN ); A_SHAUpdateNS( &shaContext, IHash1, A_SHA_DIGEST_LEN ); A_SHAFinalNS( &shaContext, OutputHash ); // // round 8 // OutputHash += A_SHA_DIGEST_LEN; A_SHAInit( &shaContext ); A_SHAUpdateNS( &shaContext, IHash4, A_SHA_DIGEST_LEN ); A_SHAUpdateNS( &shaContext, IHash2, A_SHA_DIGEST_LEN ); A_SHAFinalNS( &shaContext, OutputHash ); RtlSecureZeroMemory( &shaContext, sizeof(shaContext) ); RtlSecureZeroMemory( IntermediateHashes, sizeof(IntermediateHashes) ); return TRUE; }