Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Abstract:
  4. Build up a "Very Large Hash" based on arbitrary sized input data
  5. of size cbData specified by the pvData buffer.
  6. This implementation updates a 640bit hash, which is internally based on
  7. multiple invocations of a modified SHA-1 which doesn't implement endian
  8. conversion internally.
  9. Author:
  10. Scott Field (sfield) 24-Sep-98
  11. --*/
  12. #ifndef KMODE_RNG
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #else
  18. #include <ntifs.h>
  19. #include <windef.h>
  20. #endif // KMODE_RNG
  21. #include <sha.h>
  22. #include "vlhash.h"
  23. #ifdef KMODE_RNG
  24. #ifdef ALLOC_PRAGMA
  25. #pragma alloc_text(PAGE, VeryLargeHashUpdate)
  26. #endif // ALLOC_PRAGMA
  27. #endif // KMODE_RNG
  28. BOOL
  29. VeryLargeHashUpdate(
  30. IN VOID *pvData, // data from perfcounters, user supplied, etc.
  31. IN DWORD cbData,
  32. IN OUT BYTE VeryLargeHash[A_SHA_DIGEST_LEN * 4]
  33. )
  34. {
  35. //
  36. // pointers to 1/4 size chunks of seed pointed to by VeryLargeHash
  37. //
  38. DWORD cbSeedChunk;
  39. PBYTE pSeed1;
  40. PBYTE pSeed2;
  41. PBYTE pSeed3;
  42. PBYTE pSeed4;
  43. //
  44. // pointers to 1/4 size chunks of data pointed to by pData
  45. //
  46. DWORD cbDataChunk;
  47. PBYTE pData1;
  48. PBYTE pData2;
  49. PBYTE pData3;
  50. PBYTE pData4;
  51. //
  52. // pointers to individual intermediate hash within IntermediateHashes
  53. //
  54. PBYTE IHash1;
  55. PBYTE IHash2;
  56. PBYTE IHash3;
  57. PBYTE IHash4;
  58. BYTE IntermediateHashes[ A_SHA_DIGEST_LEN * 4 ];
  59. //
  60. // pointer to output hash within VeryLargeHash buffer.
  61. //
  62. PBYTE OutputHash;
  63. A_SHA_CTX shaContext;
  64. #ifdef KMODE_RNG
  65. PAGED_CODE();
  66. #endif // KMODE_RNG
  67. //
  68. // check parameters
  69. //
  70. if( VeryLargeHash == NULL || pvData == NULL )
  71. return FALSE;
  72. //
  73. // break up input blocks into 1/4 size chunks.
  74. //
  75. cbSeedChunk = A_SHA_DIGEST_LEN;
  76. cbDataChunk = cbData / 4;
  77. if( cbDataChunk == 0 )
  78. return FALSE;
  79. pSeed1 = VeryLargeHash;
  80. pSeed2 = pSeed1 + cbSeedChunk;
  81. pData1 = (PBYTE)pvData;
  82. pData2 = pData1 + cbDataChunk;
  83. IHash1 = IntermediateHashes;
  84. IHash2 = IHash1 + A_SHA_DIGEST_LEN;
  85. //
  86. // round 1
  87. //
  88. A_SHAInit( &shaContext );
  89. A_SHAUpdateNS( &shaContext, pSeed1, cbSeedChunk );
  90. A_SHAUpdateNS( &shaContext, pData1, cbDataChunk );
  91. A_SHAUpdateNS( &shaContext, pSeed2, cbSeedChunk );
  92. A_SHAUpdateNS( &shaContext, pData2, cbDataChunk );
  93. A_SHAFinalNS( &shaContext, IHash1 );
  94. //
  95. // round 2
  96. //
  97. A_SHAInit( &shaContext );
  98. A_SHAUpdateNS( &shaContext, pSeed2, cbSeedChunk );
  99. A_SHAUpdateNS( &shaContext, pData2, cbDataChunk );
  100. A_SHAUpdateNS( &shaContext, pSeed1, cbSeedChunk );
  101. A_SHAUpdateNS( &shaContext, pData1, cbDataChunk );
  102. A_SHAFinalNS( &shaContext, IHash2 );
  103. pSeed3 = pSeed2 + cbSeedChunk;
  104. pSeed4 = pSeed3 + cbSeedChunk;
  105. pData3 = pData2 + cbDataChunk;
  106. pData4 = pData3 + cbDataChunk;
  107. IHash3 = IHash2 + A_SHA_DIGEST_LEN;
  108. IHash4 = IHash3 + A_SHA_DIGEST_LEN;
  109. //
  110. // round 3
  111. //
  112. A_SHAInit( &shaContext );
  113. A_SHAUpdateNS( &shaContext, pSeed3, cbSeedChunk );
  114. A_SHAUpdateNS( &shaContext, pData3, cbDataChunk );
  115. A_SHAUpdateNS( &shaContext, pSeed4, cbSeedChunk );
  116. A_SHAUpdateNS( &shaContext, pData4, cbDataChunk );
  117. A_SHAFinalNS( &shaContext, IHash3 );
  118. //
  119. // round 4
  120. //
  121. A_SHAInit( &shaContext );
  122. A_SHAUpdateNS( &shaContext, pSeed4, cbSeedChunk );
  123. A_SHAUpdateNS( &shaContext, pData4, cbDataChunk );
  124. A_SHAUpdateNS( &shaContext, pSeed3, cbSeedChunk );
  125. A_SHAUpdateNS( &shaContext, pData3, cbDataChunk );
  126. A_SHAFinalNS( &shaContext, IHash4 );
  127. //
  128. // round 5
  129. //
  130. OutputHash = VeryLargeHash;
  131. A_SHAInit( &shaContext );
  132. A_SHAUpdateNS( &shaContext, IHash1, A_SHA_DIGEST_LEN );
  133. A_SHAUpdateNS( &shaContext, IHash3, A_SHA_DIGEST_LEN );
  134. A_SHAFinalNS( &shaContext, OutputHash );
  135. //
  136. // round 6
  137. //
  138. OutputHash += A_SHA_DIGEST_LEN;
  139. A_SHAInit( &shaContext );
  140. A_SHAUpdateNS( &shaContext, IHash2, A_SHA_DIGEST_LEN );
  141. A_SHAUpdateNS( &shaContext, IHash4, A_SHA_DIGEST_LEN );
  142. A_SHAFinalNS( &shaContext, OutputHash );
  143. //
  144. // round 7
  145. //
  146. OutputHash += A_SHA_DIGEST_LEN;
  147. A_SHAInit( &shaContext );
  148. A_SHAUpdateNS( &shaContext, IHash3, A_SHA_DIGEST_LEN );
  149. A_SHAUpdateNS( &shaContext, IHash1, A_SHA_DIGEST_LEN );
  150. A_SHAFinalNS( &shaContext, OutputHash );
  151. //
  152. // round 8
  153. //
  154. OutputHash += A_SHA_DIGEST_LEN;
  155. A_SHAInit( &shaContext );
  156. A_SHAUpdateNS( &shaContext, IHash4, A_SHA_DIGEST_LEN );
  157. A_SHAUpdateNS( &shaContext, IHash2, A_SHA_DIGEST_LEN );
  158. A_SHAFinalNS( &shaContext, OutputHash );
  159. RtlSecureZeroMemory( &shaContext, sizeof(shaContext) );
  160. RtlSecureZeroMemory( IntermediateHashes, sizeof(IntermediateHashes) );
  161. return TRUE;
  162. }