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.

680 lines
20 KiB

  1. #include "windows.h"
  2. #include "stdlib.h"
  3. #include "stdio.h"
  4. #include "fastsha1.h"
  5. //
  6. // Note - these numbers are from the FIPS-180-1 standard documentation.
  7. // Don't change them, period.
  8. //
  9. #define FASTSHA1_STATE_INITIAL_H0 (0x67452301)
  10. #define FASTSHA1_STATE_INITIAL_H1 (0xEFCDAB89)
  11. #define FASTSHA1_STATE_INITIAL_H2 (0x98BADCFE)
  12. #define FASTSHA1_STATE_INITIAL_H3 (0x10325476)
  13. #define FASTSHA1_STATE_INITIAL_H4 (0xC3D2E1F0)
  14. #define FASTSHA1_FINALIZATION_BYTE (0x80)
  15. #define HVALUE( state, which ) ( (state).dwHValues[which] )
  16. #define SHA1STATE_A(state) (HVALUE(state, 0))
  17. #define SHA1STATE_B(state) (HVALUE(state, 1))
  18. #define SHA1STATE_C(state) (HVALUE(state, 2))
  19. #define SHA1STATE_D(state) (HVALUE(state, 3))
  20. #define SHA1STATE_E(state) (HVALUE(state, 4))
  21. #define BLOCK_WORD_LENGTH ( 16 )
  22. #define SHA1_HASH_RESULT_SIZE ( 20 )
  23. #define BITS_PER_BYTE ( 8 )
  24. static SHA_WORD __fastcall swap_order( SHA_WORD w )
  25. {
  26. return ( ( ( (w) >> 24 ) & 0x000000FFL ) |
  27. ( ( (w) >> 8 ) & 0x0000FF00L ) |
  28. ( ( (w) << 8 ) & 0x00FF0000L ) |
  29. ( ( (w) << 24 ) & 0xFF000000L ) );
  30. }
  31. /*
  32. b c d b&c ~b ~b&d (b&c)|(~b&d)
  33. 0 0 0 0 1 0 0
  34. 0 0 1 0 1 1 1
  35. 0 1 0 0 1 0 0
  36. 0 1 1 0 1 1 1
  37. 1 0 0 0 0 0 0
  38. 1 0 1 0 0 0 0
  39. 1 1 0 1 0 0 1
  40. 1 1 1 1 0 0 1
  41. */
  42. #define F_00( b, c, d ) ( ( (b) & (c) ) | ( ~(b) & (d) ) )
  43. /*
  44. b c d b^c b^c^d
  45. 0 0 0 0 0
  46. 0 0 1 0 1
  47. 0 1 0 1 1
  48. 0 1 1 1 0
  49. 1 0 0 1 1
  50. 1 0 1 1 0
  51. 1 1 0 0 0
  52. 1 1 1 0 1
  53. */
  54. #define F_01( b, c, d ) ( (b) ^ (c) ^ (d) )
  55. /*
  56. b c d b&c b&d c&d |
  57. 0 0 0 0 0 0 0
  58. 0 0 1 0 0 0 0
  59. 0 1 0 0 0 0 0
  60. 0 1 1 0 0 1 1
  61. 1 0 0 0 0 0 0
  62. 1 0 1 0 1 0 1
  63. 1 1 0 1 0 0 1
  64. 1 1 1 1 1 1 1
  65. c&d | (b&(c|d))
  66. */
  67. //#define F_02( b, c, d ) ( ( (b) & (c) ) | ( (b) & (d) ) | ( (c) & (d) ) )
  68. #define F_02( b, c, d ) ( ( (c) & (d) ) | ( (b) & ( (c) | (d) ) ) )
  69. #define F_03( b, c, d ) ( (b) ^ (c) ^ (d) )
  70. static
  71. BOOL
  72. __FastSHA1HashPreparedMessage(
  73. PFASTSHA1_STATE pState,
  74. SHA_WORD* pdwMessage
  75. );
  76. BOOL
  77. InitializeFastSHA1State(
  78. DWORD dwFlags,
  79. PFASTSHA1_STATE pState
  80. )
  81. {
  82. BOOL bOk = FALSE;
  83. if ( ( !pState ) ||
  84. ( pState->cbStruct < sizeof( FASTSHA1_STATE ) ) ||
  85. ( dwFlags != 0 ) )
  86. {
  87. SetLastError( ERROR_INVALID_PARAMETER );
  88. goto Exit;
  89. }
  90. pState->bIsSha1Locked = FALSE;
  91. ZeroMemory( pState->bLatestMessage, sizeof( pState->bLatestMessage ) );
  92. pState->bLatestMessageSize = 0;
  93. pState->cbTotalMessageSizeInBytes.QuadPart = 0;
  94. HVALUE( *pState, 0 ) = FASTSHA1_STATE_INITIAL_H0;
  95. HVALUE( *pState, 1 ) = FASTSHA1_STATE_INITIAL_H1;
  96. HVALUE( *pState, 2 ) = FASTSHA1_STATE_INITIAL_H2;
  97. HVALUE( *pState, 3 ) = FASTSHA1_STATE_INITIAL_H3;
  98. HVALUE( *pState, 4 ) = FASTSHA1_STATE_INITIAL_H4;
  99. bOk = TRUE;
  100. Exit:
  101. return bOk;
  102. }
  103. BOOL
  104. FinalizeFastSHA1State(
  105. DWORD dwFlags,
  106. PFASTSHA1_STATE pState
  107. )
  108. /*++
  109. Finalizing a SHA1 hash locks the hash state so its value can be queried.
  110. It also ensures that the right padding is done w.r.t. the total bit length
  111. and whatnot required by the SHA1 hash spec.
  112. 1 - This should have been called right after a HashMoreFastSHA1Data, so either
  113. the buffer is entirely empty, or it's got at least eight bits left.
  114. 2 - Figure out what the last byte in the message is (easy enough). The next
  115. byte should be set to 0x80 - 10000000b.
  116. 3 - If this buffer has less than
  117. --*/
  118. {
  119. BOOL bOk = FALSE;
  120. LARGE_INTEGER TotalBitsInMessage;
  121. LARGE_INTEGER *pMsgSizeLocation;
  122. if ( ( !pState ) ||
  123. ( pState->cbStruct < sizeof(FASTSHA1_STATE ) ) ||
  124. ( pState->bIsSha1Locked ) ||
  125. ( dwFlags != 0 ) )
  126. {
  127. SetLastError( ERROR_INVALID_PARAMETER );
  128. goto Exit;
  129. }
  130. //
  131. // Finalize the SHA1 state data. This is annoying, but not difficult..
  132. //
  133. //
  134. // When we're in this state, we should have at least one byte of data left over to
  135. // or in our final flag. If not, something bad happened at some point along the
  136. // line.
  137. //
  138. if ( ( pState->bLatestMessageSize - SHA1_MESSAGE_BYTE_LENGTH ) < 1 )
  139. {
  140. SetLastError( ERROR_INTERNAL_ERROR );
  141. goto Exit;
  142. }
  143. //
  144. // Into the byte right after the last one we have seen so far, inject a high-bit
  145. // one. This translates to 0x80 (see the #define above), since we don't deal in
  146. // non-integral-byte-numbers of bits. This bit does NOT change the total number of
  147. // bits in the message!
  148. //
  149. pState->bLatestMessage[pState->bLatestMessageSize++] = FASTSHA1_FINALIZATION_BYTE;
  150. //
  151. // We need some space to put the bit count to this point. If we don't have at least
  152. // two sha-words (64 bits) in the end of the message, then we need to add this blob
  153. // of bits to the resulting hash so far.
  154. //
  155. if ( ( SHA1_MESSAGE_BYTE_LENGTH - pState->bLatestMessageSize ) < ( sizeof(SHA_WORD) * 2 ) )
  156. {
  157. __FastSHA1HashPreparedMessage( pState, (SHA_WORD*)pState->bLatestMessage );
  158. ZeroMemory( pState->bLatestMessage, sizeof(pState->bLatestMessage) );
  159. pState->bLatestMessageSize = 0;
  160. }
  161. //
  162. // Now stick the byte count at the end of the blob
  163. //
  164. TotalBitsInMessage.QuadPart = pState->cbTotalMessageSizeInBytes.QuadPart * BITS_PER_BYTE;
  165. //
  166. // Point our size thing at the right place
  167. //
  168. pMsgSizeLocation = (LARGE_INTEGER*)(pState->bLatestMessage + (SHA1_MESSAGE_BYTE_LENGTH - (sizeof(SHA_WORD)*2)));
  169. //
  170. // This bit of a mess actually puts the length bits in the right order.
  171. //
  172. pMsgSizeLocation->LowPart = swap_order( TotalBitsInMessage.HighPart );
  173. pMsgSizeLocation->HighPart = swap_order( TotalBitsInMessage.LowPart );
  174. //
  175. // And run the hash over this final blob
  176. //
  177. __FastSHA1HashPreparedMessage( pState, (SHA_WORD*)pState->bLatestMessage );
  178. //
  179. // Rotate our bits around. This has the unintended side-effect of locking
  180. // the blob of H-values by messing with their byte order. All the modifying functions
  181. // (except initialize) will choke if you try and do something like hash more data
  182. // with a locked state.
  183. //
  184. pState->dwHValues[0] = swap_order( pState->dwHValues[0] );
  185. pState->dwHValues[1] = swap_order( pState->dwHValues[1] );
  186. pState->dwHValues[2] = swap_order( pState->dwHValues[2] );
  187. pState->dwHValues[3] = swap_order( pState->dwHValues[3] );
  188. pState->dwHValues[4] = swap_order( pState->dwHValues[4] );
  189. //
  190. // We're done!
  191. //
  192. pState->bIsSha1Locked = TRUE;
  193. bOk = TRUE;
  194. Exit:
  195. return bOk;
  196. }
  197. BOOL
  198. GetFastSHA1Result( PFASTSHA1_STATE pState, PBYTE pdwDestination, PSIZE_T cbDestination )
  199. {
  200. BOOL bOk = FALSE;
  201. SHA_WORD *pSrc, *pDst;
  202. //
  203. // If you are seeing this, something bad has happened with the sizes of things.
  204. //
  205. C_ASSERT( SHA1_HASH_RESULT_SIZE == 20 );
  206. C_ASSERT( SHA1_HASH_RESULT_SIZE == sizeof(pState->dwHValues) );
  207. if ( !pState || !cbDestination )
  208. {
  209. SetLastError( ERROR_INVALID_PARAMETER );
  210. goto Exit;
  211. }
  212. //
  213. // No fair getting the internal state until you're done with the sha1.
  214. // IE: Call FinalizeFastSHA1Hash() before requesting the result.
  215. //
  216. if ( !pState->bIsSha1Locked )
  217. {
  218. SetLastError( ERROR_INVALID_STATE );
  219. goto Exit;
  220. }
  221. //
  222. // If there's no destination specified, then we'll need to tell them how big
  223. // the data really is.
  224. //
  225. if ( !pdwDestination )
  226. {
  227. *cbDestination = SHA1_HASH_RESULT_SIZE;
  228. SetLastError( ERROR_INSUFFICIENT_BUFFER );
  229. goto Exit;
  230. }
  231. //
  232. // Otherwise, copy the state out of the state object and into the desination
  233. //
  234. pSrc = pState->dwHValues;
  235. pDst = (SHA_WORD*)pdwDestination;
  236. pDst[0] = pSrc[0];
  237. pDst[1] = pSrc[1];
  238. pDst[2] = pSrc[2];
  239. pDst[3] = pSrc[3];
  240. pDst[4] = pSrc[4];
  241. bOk = TRUE;
  242. Exit:
  243. return bOk;
  244. }
  245. //
  246. // These define the core functions of the bit-twiddling in the SHA1 hash
  247. // routine. If you want optimization, try these first.
  248. // RotateBitsLeft could probably get a boost if we used rol/ror on x86.
  249. //
  250. #define RotateBitsLeft( w, sh ) ( ( w << sh ) | ( w >> ( 32 - sh ) ) )
  251. #define fidgetcore( f, cnst, i ) \
  252. Temp = cnst + E + WorkBuffer[i] + f( B, C, D ) + RotateBitsLeft( A, 5 ); \
  253. E = D; \
  254. D = C; \
  255. C = RotateBitsLeft( B, 30 ); \
  256. B = A; \
  257. A = Temp;
  258. static void
  259. __fastcall __FastSHA1TwiddleBitsCore( SHA_WORD *state, SHA_WORD *WorkBuffer )
  260. {
  261. register SHA_WORD A, B, C, D, E, Temp;
  262. register SHA_WORD i;
  263. A = state[0];
  264. B = state[1];
  265. C = state[2];
  266. D = state[3];
  267. E = state[4];
  268. i = 0;
  269. {
  270. // Temp = RotateBitsLeft( A, 5 ) + E + WorkBuffer[i] + F_00(B,C,D) + 0x5a827999;
  271. fidgetcore( F_00, 0x5a827999, i++ );
  272. fidgetcore( F_00, 0x5a827999, i++ );
  273. fidgetcore( F_00, 0x5a827999, i++ );
  274. fidgetcore( F_00, 0x5a827999, i++ );
  275. fidgetcore( F_00, 0x5a827999, i++ );
  276. fidgetcore( F_00, 0x5a827999, i++ );
  277. fidgetcore( F_00, 0x5a827999, i++ );
  278. fidgetcore( F_00, 0x5a827999, i++ );
  279. fidgetcore( F_00, 0x5a827999, i++ );
  280. fidgetcore( F_00, 0x5a827999, i++ );
  281. fidgetcore( F_00, 0x5a827999, i++ );
  282. fidgetcore( F_00, 0x5a827999, i++ );
  283. fidgetcore( F_00, 0x5a827999, i++ );
  284. fidgetcore( F_00, 0x5a827999, i++ );
  285. fidgetcore( F_00, 0x5a827999, i++ );
  286. fidgetcore( F_00, 0x5a827999, i++ );
  287. fidgetcore( F_00, 0x5a827999, i++ );
  288. fidgetcore( F_00, 0x5a827999, i++ );
  289. fidgetcore( F_00, 0x5a827999, i++ );
  290. fidgetcore( F_00, 0x5a827999, i++ );
  291. }
  292. {
  293. fidgetcore( F_01, 0x6ed9eba1, i++ );
  294. fidgetcore( F_01, 0x6ed9eba1, i++ );
  295. fidgetcore( F_01, 0x6ed9eba1, i++ );
  296. fidgetcore( F_01, 0x6ed9eba1, i++ );
  297. fidgetcore( F_01, 0x6ed9eba1, i++ );
  298. fidgetcore( F_01, 0x6ed9eba1, i++ );
  299. fidgetcore( F_01, 0x6ed9eba1, i++ );
  300. fidgetcore( F_01, 0x6ed9eba1, i++ );
  301. fidgetcore( F_01, 0x6ed9eba1, i++ );
  302. fidgetcore( F_01, 0x6ed9eba1, i++ );
  303. fidgetcore( F_01, 0x6ed9eba1, i++ );
  304. fidgetcore( F_01, 0x6ed9eba1, i++ );
  305. fidgetcore( F_01, 0x6ed9eba1, i++ );
  306. fidgetcore( F_01, 0x6ed9eba1, i++ );
  307. fidgetcore( F_01, 0x6ed9eba1, i++ );
  308. fidgetcore( F_01, 0x6ed9eba1, i++ );
  309. fidgetcore( F_01, 0x6ed9eba1, i++ );
  310. fidgetcore( F_01, 0x6ed9eba1, i++ );
  311. fidgetcore( F_01, 0x6ed9eba1, i++ );
  312. fidgetcore( F_01, 0x6ed9eba1, i++ );
  313. }
  314. {
  315. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  316. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  317. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  318. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  319. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  320. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  321. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  322. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  323. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  324. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  325. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  326. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  327. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  328. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  329. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  330. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  331. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  332. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  333. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  334. fidgetcore( F_02, 0x8f1bbcdc, i++ );
  335. }
  336. {
  337. fidgetcore( F_03, 0xca62c1d6, i++ );
  338. fidgetcore( F_03, 0xca62c1d6, i++ );
  339. fidgetcore( F_03, 0xca62c1d6, i++ );
  340. fidgetcore( F_03, 0xca62c1d6, i++ );
  341. fidgetcore( F_03, 0xca62c1d6, i++ );
  342. fidgetcore( F_03, 0xca62c1d6, i++ );
  343. fidgetcore( F_03, 0xca62c1d6, i++ );
  344. fidgetcore( F_03, 0xca62c1d6, i++ );
  345. fidgetcore( F_03, 0xca62c1d6, i++ );
  346. fidgetcore( F_03, 0xca62c1d6, i++ );
  347. fidgetcore( F_03, 0xca62c1d6, i++ );
  348. fidgetcore( F_03, 0xca62c1d6, i++ );
  349. fidgetcore( F_03, 0xca62c1d6, i++ );
  350. fidgetcore( F_03, 0xca62c1d6, i++ );
  351. fidgetcore( F_03, 0xca62c1d6, i++ );
  352. fidgetcore( F_03, 0xca62c1d6, i++ );
  353. fidgetcore( F_03, 0xca62c1d6, i++ );
  354. fidgetcore( F_03, 0xca62c1d6, i++ );
  355. fidgetcore( F_03, 0xca62c1d6, i++ );
  356. fidgetcore( F_03, 0xca62c1d6, i++ );
  357. }
  358. state[0] += A;
  359. state[1] += B;
  360. state[2] += C;
  361. state[3] += D;
  362. state[4] += E;
  363. }
  364. static
  365. BOOL
  366. __FastSHA1HashPreparedMessage(
  367. PFASTSHA1_STATE pState,
  368. SHA_WORD* pdwMessage
  369. )
  370. {
  371. BOOL bOk = FALSE;
  372. //
  373. // This function makes a few assumptions. First, it assumes that pdwMessage really
  374. // is 16 sha-words long. If that's not the case, prepare yourself for some
  375. // ugly errors. That's why this is static inline - don't be calling this except
  376. // via HashMoreFastSHA1Data.
  377. //
  378. SHA_WORD WorkBuffer[80];
  379. register SHA_WORD A, B, C, D, E;
  380. register SHA_WORD Temp;
  381. register int t;
  382. if ( !pdwMessage || !pState )
  383. {
  384. SetLastError( ERROR_INVALID_PARAMETER );
  385. goto Exit;
  386. }
  387. if ( pState->bIsSha1Locked )
  388. {
  389. SetLastError( ERROR_INVALID_STATE );
  390. goto Exit;
  391. }
  392. // Loop unrolling seemed to help a little
  393. {
  394. register SHA_WORD *pWB = WorkBuffer;
  395. register SHA_WORD *pMSG = pdwMessage;
  396. t = 16;
  397. while ( t ) {
  398. *(pWB+0) = swap_order( *(pMSG+0) );
  399. *(pWB+1) = swap_order( *(pMSG+1) );
  400. *(pWB+2) = swap_order( *(pMSG+2) );
  401. *(pWB+3) = swap_order( *(pMSG+3) );
  402. pWB+=4;
  403. pMSG+=4;
  404. t-=4;
  405. }
  406. }
  407. {
  408. register SHA_WORD *pWB = WorkBuffer+16;
  409. register SHA_WORD *pWBm3 = pWB-3;
  410. register SHA_WORD *pWBm8 = pWB-8;
  411. register SHA_WORD *pWBm14 = pWB-14;
  412. register SHA_WORD *pWBm16 = pWB-16;
  413. register DWORD i = 80 - 16;
  414. while ( i ) {
  415. *(pWB+0) = *(pWBm3+0) ^ *(pWBm8+0) ^ *(pWBm14+0) ^ *(pWBm16+0);
  416. *(pWB+1) = *(pWBm3+1) ^ *(pWBm8+1) ^ *(pWBm14+1) ^ *(pWBm16+1);
  417. *(pWB+2) = *(pWBm3+2) ^ *(pWBm8+2) ^ *(pWBm14+2) ^ *(pWBm16+2);
  418. *(pWB+3) = *(pWBm3+3) ^ *(pWBm8+3) ^ *(pWBm14+3) ^ *(pWBm16+3);
  419. *(pWB+4) = *(pWBm3+4) ^ *(pWBm8+4) ^ *(pWBm14+4) ^ *(pWBm16+4);
  420. *(pWB+5) = *(pWBm3+5) ^ *(pWBm8+5) ^ *(pWBm14+5) ^ *(pWBm16+5);
  421. *(pWB+6) = *(pWBm3+6) ^ *(pWBm8+6) ^ *(pWBm14+6) ^ *(pWBm16+6);
  422. *(pWB+7) = *(pWBm3+7) ^ *(pWBm8+7) ^ *(pWBm14+7) ^ *(pWBm16+7);
  423. pWB += 8;
  424. i -= 8;
  425. }
  426. }
  427. //
  428. // Part c - Start off the A-F values
  429. //
  430. // A = H_0, B = H_1, C = H_2, D = H_3, E = H_4
  431. //
  432. __FastSHA1TwiddleBitsCore( pState->dwHValues, WorkBuffer );
  433. bOk = TRUE;
  434. Exit:
  435. return bOk;
  436. }
  437. void __fastcall
  438. __ZeroFastSHA1Message( PFASTSHA1_STATE pState )
  439. {
  440. SHA_WORD *pStateData = (SHA_WORD*)pState->bLatestMessage;
  441. pState->bLatestMessageSize = 0;
  442. pStateData[0x0] = 0x0;
  443. pStateData[0x1] = 0;
  444. pStateData[0x2] = 0;
  445. pStateData[0x3] = 0;
  446. pStateData[0x4] = 0;
  447. pStateData[0x5] = 0;
  448. pStateData[0x6] = 0;
  449. pStateData[0x7] = 0;
  450. pStateData[0x8] = 0;
  451. pStateData[0x9] = 0;
  452. pStateData[0xa] = 0;
  453. pStateData[0xb] = 0;
  454. pStateData[0xc] = 0;
  455. pStateData[0xd] = 0;
  456. pStateData[0xe] = 0;
  457. pStateData[0xf] = 0;
  458. }
  459. BOOL
  460. HashMoreFastSHA1Data( PFASTSHA1_STATE pState, PBYTE pbData, SIZE_T cbData )
  461. {
  462. BOOL bOk = FALSE;
  463. ULONG cbStreamBlocksThisRound, cbStreamBytesLeftAtEnd;
  464. if ( !pState || !pbData )
  465. {
  466. SetLastError( ERROR_INVALID_PARAMETER );
  467. goto Exit;
  468. }
  469. if ( pState->bIsSha1Locked )
  470. {
  471. SetLastError( ERROR_INVALID_STATE );
  472. goto Exit;
  473. }
  474. pState->cbTotalMessageSizeInBytes.QuadPart += cbData;
  475. //
  476. // Start off by filling in the pending message buffer block if we can.
  477. //
  478. if ( pState->bLatestMessageSize != 0 )
  479. {
  480. //
  481. // Copy into our internal state buffer, then hash what we found.
  482. //
  483. SIZE_T cbFiller = sizeof(pState->bLatestMessage) - pState->bLatestMessageSize;
  484. cbFiller = ( cbFiller > cbData ? cbData : cbFiller );
  485. memcpy( pState->bLatestMessage + pState->bLatestMessageSize, pbData, cbFiller );
  486. //
  487. // Bookkeeping
  488. //
  489. cbData -= cbFiller;
  490. pbData += cbFiller;
  491. pState->bLatestMessageSize += cbFiller;
  492. //
  493. // If that got us up to a full message, then update state.
  494. //
  495. if ( pState->bLatestMessageSize == SHA1_MESSAGE_BYTE_LENGTH )
  496. {
  497. __FastSHA1HashPreparedMessage( pState, (SHA_WORD*)pState->bLatestMessage );
  498. __ZeroFastSHA1Message( pState );
  499. }
  500. //
  501. // Otherwise, we still don't have enough to fill up a single buffer, so don't
  502. // bother doing anything else here.
  503. //
  504. else
  505. {
  506. bOk = TRUE;
  507. goto Exit;
  508. }
  509. }
  510. //
  511. // Now that we've aligned our buffer, find out how many blocks we can process in
  512. // this input stream.
  513. //
  514. cbStreamBlocksThisRound = cbData / SHA1_MESSAGE_BYTE_LENGTH;
  515. cbStreamBytesLeftAtEnd = cbData % SHA1_MESSAGE_BYTE_LENGTH;
  516. //
  517. // Spin through all the full blocks
  518. //
  519. if ( cbStreamBlocksThisRound )
  520. {
  521. while ( cbStreamBlocksThisRound-- )
  522. {
  523. __FastSHA1HashPreparedMessage( pState, (SHA_WORD*)pbData );
  524. pbData += SHA1_MESSAGE_BYTE_LENGTH;
  525. }
  526. __ZeroFastSHA1Message( pState );
  527. }
  528. //
  529. // And account for leftovers
  530. //
  531. if ( cbStreamBytesLeftAtEnd )
  532. {
  533. pState->bLatestMessageSize = cbStreamBytesLeftAtEnd;
  534. memcpy( pState->bLatestMessage, pbData, cbStreamBytesLeftAtEnd );
  535. ZeroMemory( pState->bLatestMessage + cbStreamBytesLeftAtEnd, SHA1_MESSAGE_BYTE_LENGTH - cbStreamBytesLeftAtEnd );
  536. }
  537. bOk = TRUE;
  538. Exit:
  539. return bOk;
  540. }
  541. BOOL
  542. CompareFashSHA1Hashes(
  543. PFASTSHA1_STATE pStateLeft,
  544. PFASTSHA1_STATE pStateRight,
  545. BOOL *pbComparesEqual
  546. )
  547. {
  548. BOOL bOk = FALSE;
  549. if ( pbComparesEqual ) *pbComparesEqual = FALSE;
  550. if ( !pStateLeft || !pStateRight || !pbComparesEqual )
  551. {
  552. SetLastError( ERROR_INVALID_PARAMETER );
  553. goto Exit;
  554. }
  555. if ( !pStateLeft->bIsSha1Locked || !pStateRight->bIsSha1Locked )
  556. {
  557. SetLastError( ERROR_INVALID_PARAMETER );
  558. goto Exit;
  559. }
  560. //
  561. // Easy way out: compare the two blobs of H's to see if they're equal.
  562. //
  563. *pbComparesEqual = ( memcmp(
  564. pStateLeft->dwHValues,
  565. pStateRight->dwHValues,
  566. sizeof(SHA_WORD)*5 ) == 0 );
  567. bOk = TRUE;
  568. Exit:
  569. return bOk;
  570. }