SHA1.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "mozilla/Assertions.h"
  6. #include "mozilla/EndianUtils.h"
  7. #include "mozilla/SHA1.h"
  8. #include <string.h>
  9. using mozilla::NativeEndian;
  10. using mozilla::SHA1Sum;
  11. static inline uint32_t
  12. SHA_ROTL(uint32_t aT, uint32_t aN)
  13. {
  14. MOZ_ASSERT(aN < 32);
  15. return (aT << aN) | (aT >> (32 - aN));
  16. }
  17. static void
  18. shaCompress(volatile unsigned* aX, const uint32_t* aBuf);
  19. #define SHA_F1(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z))
  20. #define SHA_F2(X, Y, Z) ((X) ^ (Y) ^ (Z))
  21. #define SHA_F3(X, Y, Z) (((X) & (Y)) | ((Z) & ((X) | (Y))))
  22. #define SHA_F4(X, Y, Z) ((X) ^ (Y) ^ (Z))
  23. #define SHA_MIX(n, a, b, c) XW(n) = SHA_ROTL(XW(a) ^ XW(b) ^ XW(c) ^XW(n), 1)
  24. SHA1Sum::SHA1Sum()
  25. : mSize(0), mDone(false)
  26. {
  27. // Initialize H with constants from FIPS180-1.
  28. mH[0] = 0x67452301L;
  29. mH[1] = 0xefcdab89L;
  30. mH[2] = 0x98badcfeL;
  31. mH[3] = 0x10325476L;
  32. mH[4] = 0xc3d2e1f0L;
  33. }
  34. /*
  35. * Explanation of H array and index values:
  36. *
  37. * The context's H array is actually the concatenation of two arrays
  38. * defined by SHA1, the H array of state variables (5 elements),
  39. * and the W array of intermediate values, of which there are 16 elements.
  40. * The W array starts at H[5], that is W[0] is H[5].
  41. * Although these values are defined as 32-bit values, we use 64-bit
  42. * variables to hold them because the AMD64 stores 64 bit values in
  43. * memory MUCH faster than it stores any smaller values.
  44. *
  45. * Rather than passing the context structure to shaCompress, we pass
  46. * this combined array of H and W values. We do not pass the address
  47. * of the first element of this array, but rather pass the address of an
  48. * element in the middle of the array, element X. Presently X[0] is H[11].
  49. * So we pass the address of H[11] as the address of array X to shaCompress.
  50. * Then shaCompress accesses the members of the array using positive AND
  51. * negative indexes.
  52. *
  53. * Pictorially: (each element is 8 bytes)
  54. * H | H0 H1 H2 H3 H4 W0 W1 W2 W3 W4 W5 W6 W7 W8 W9 Wa Wb Wc Wd We Wf |
  55. * X |-11-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 |
  56. *
  57. * The byte offset from X[0] to any member of H and W is always
  58. * representable in a signed 8-bit value, which will be encoded
  59. * as a single byte offset in the X86-64 instruction set.
  60. * If we didn't pass the address of H[11], and instead passed the
  61. * address of H[0], the offsets to elements H[16] and above would be
  62. * greater than 127, not representable in a signed 8-bit value, and the
  63. * x86-64 instruction set would encode every such offset as a 32-bit
  64. * signed number in each instruction that accessed element H[16] or
  65. * higher. This results in much bigger and slower code.
  66. */
  67. #define H2X 11 /* X[0] is H[11], and H[0] is X[-11] */
  68. #define W2X 6 /* X[0] is W[6], and W[0] is X[-6] */
  69. /*
  70. * SHA: Add data to context.
  71. */
  72. void
  73. SHA1Sum::update(const void* aData, uint32_t aLen)
  74. {
  75. MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
  76. const uint8_t* data = static_cast<const uint8_t*>(aData);
  77. if (aLen == 0) {
  78. return;
  79. }
  80. /* Accumulate the byte count. */
  81. unsigned int lenB = static_cast<unsigned int>(mSize) & 63U;
  82. mSize += aLen;
  83. /* Read the data into W and process blocks as they get full. */
  84. unsigned int togo;
  85. if (lenB > 0) {
  86. togo = 64U - lenB;
  87. if (aLen < togo) {
  88. togo = aLen;
  89. }
  90. memcpy(mU.mB + lenB, data, togo);
  91. aLen -= togo;
  92. data += togo;
  93. lenB = (lenB + togo) & 63U;
  94. if (!lenB) {
  95. shaCompress(&mH[H2X], mU.mW);
  96. }
  97. }
  98. while (aLen >= 64U) {
  99. aLen -= 64U;
  100. shaCompress(&mH[H2X], reinterpret_cast<const uint32_t*>(data));
  101. data += 64U;
  102. }
  103. if (aLen > 0) {
  104. memcpy(mU.mB, data, aLen);
  105. }
  106. }
  107. /*
  108. * SHA: Generate hash value
  109. */
  110. void
  111. SHA1Sum::finish(SHA1Sum::Hash& aHashOut)
  112. {
  113. MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
  114. uint64_t size = mSize;
  115. uint32_t lenB = uint32_t(size) & 63;
  116. static const uint8_t bulk_pad[64] =
  117. { 0x80,0,0,0,0,0,0,0,0,0,
  118. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  119. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  120. /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits. */
  121. update(bulk_pad, (((55 + 64) - lenB) & 63) + 1);
  122. MOZ_ASSERT((uint32_t(mSize) & 63) == 56);
  123. /* Convert size from bytes to bits. */
  124. size <<= 3;
  125. mU.mW[14] = NativeEndian::swapToBigEndian(uint32_t(size >> 32));
  126. mU.mW[15] = NativeEndian::swapToBigEndian(uint32_t(size));
  127. shaCompress(&mH[H2X], mU.mW);
  128. /* Output hash. */
  129. mU.mW[0] = NativeEndian::swapToBigEndian(mH[0]);
  130. mU.mW[1] = NativeEndian::swapToBigEndian(mH[1]);
  131. mU.mW[2] = NativeEndian::swapToBigEndian(mH[2]);
  132. mU.mW[3] = NativeEndian::swapToBigEndian(mH[3]);
  133. mU.mW[4] = NativeEndian::swapToBigEndian(mH[4]);
  134. memcpy(aHashOut, mU.mW, 20);
  135. mDone = true;
  136. }
  137. /*
  138. * SHA: Compression function, unrolled.
  139. *
  140. * Some operations in shaCompress are done as 5 groups of 16 operations.
  141. * Others are done as 4 groups of 20 operations.
  142. * The code below shows that structure.
  143. *
  144. * The functions that compute the new values of the 5 state variables
  145. * A-E are done in 4 groups of 20 operations (or you may also think
  146. * of them as being done in 16 groups of 5 operations). They are
  147. * done by the SHA_RNDx macros below, in the right column.
  148. *
  149. * The functions that set the 16 values of the W array are done in
  150. * 5 groups of 16 operations. The first group is done by the
  151. * LOAD macros below, the latter 4 groups are done by SHA_MIX below,
  152. * in the left column.
  153. *
  154. * gcc's optimizer observes that each member of the W array is assigned
  155. * a value 5 times in this code. It reduces the number of store
  156. * operations done to the W array in the context (that is, in the X array)
  157. * by creating a W array on the stack, and storing the W values there for
  158. * the first 4 groups of operations on W, and storing the values in the
  159. * context's W array only in the fifth group. This is undesirable.
  160. * It is MUCH bigger code than simply using the context's W array, because
  161. * all the offsets to the W array in the stack are 32-bit signed offsets,
  162. * and it is no faster than storing the values in the context's W array.
  163. *
  164. * The original code for sha_fast.c prevented this creation of a separate
  165. * W array in the stack by creating a W array of 80 members, each of
  166. * whose elements is assigned only once. It also separated the computations
  167. * of the W array values and the computations of the values for the 5
  168. * state variables into two separate passes, W's, then A-E's so that the
  169. * second pass could be done all in registers (except for accessing the W
  170. * array) on machines with fewer registers. The method is suboptimal
  171. * for machines with enough registers to do it all in one pass, and it
  172. * necessitates using many instructions with 32-bit offsets.
  173. *
  174. * This code eliminates the separate W array on the stack by a completely
  175. * different means: by declaring the X array volatile. This prevents
  176. * the optimizer from trying to reduce the use of the X array by the
  177. * creation of a MORE expensive W array on the stack. The result is
  178. * that all instructions use signed 8-bit offsets and not 32-bit offsets.
  179. *
  180. * The combination of this code and the -O3 optimizer flag on GCC 3.4.3
  181. * results in code that is 3 times faster than the previous NSS sha_fast
  182. * code on AMD64.
  183. */
  184. static void
  185. shaCompress(volatile unsigned* aX, const uint32_t* aBuf)
  186. {
  187. unsigned A, B, C, D, E;
  188. #define XH(n) aX[n - H2X]
  189. #define XW(n) aX[n - W2X]
  190. #define K0 0x5a827999L
  191. #define K1 0x6ed9eba1L
  192. #define K2 0x8f1bbcdcL
  193. #define K3 0xca62c1d6L
  194. #define SHA_RND1(a, b, c, d, e, n) \
  195. a = SHA_ROTL(b, 5) + SHA_F1(c, d, e) + a + XW(n) + K0; c = SHA_ROTL(c, 30)
  196. #define SHA_RND2(a, b, c, d, e, n) \
  197. a = SHA_ROTL(b, 5) + SHA_F2(c, d, e) + a + XW(n) + K1; c = SHA_ROTL(c, 30)
  198. #define SHA_RND3(a, b, c, d, e, n) \
  199. a = SHA_ROTL(b, 5) + SHA_F3(c, d, e) + a + XW(n) + K2; c = SHA_ROTL(c, 30)
  200. #define SHA_RND4(a, b, c, d, e, n) \
  201. a = SHA_ROTL(b ,5) + SHA_F4(c, d, e) + a + XW(n) + K3; c = SHA_ROTL(c, 30)
  202. #define LOAD(n) XW(n) = NativeEndian::swapToBigEndian(aBuf[n])
  203. A = XH(0);
  204. B = XH(1);
  205. C = XH(2);
  206. D = XH(3);
  207. E = XH(4);
  208. LOAD(0); SHA_RND1(E,A,B,C,D, 0);
  209. LOAD(1); SHA_RND1(D,E,A,B,C, 1);
  210. LOAD(2); SHA_RND1(C,D,E,A,B, 2);
  211. LOAD(3); SHA_RND1(B,C,D,E,A, 3);
  212. LOAD(4); SHA_RND1(A,B,C,D,E, 4);
  213. LOAD(5); SHA_RND1(E,A,B,C,D, 5);
  214. LOAD(6); SHA_RND1(D,E,A,B,C, 6);
  215. LOAD(7); SHA_RND1(C,D,E,A,B, 7);
  216. LOAD(8); SHA_RND1(B,C,D,E,A, 8);
  217. LOAD(9); SHA_RND1(A,B,C,D,E, 9);
  218. LOAD(10); SHA_RND1(E,A,B,C,D,10);
  219. LOAD(11); SHA_RND1(D,E,A,B,C,11);
  220. LOAD(12); SHA_RND1(C,D,E,A,B,12);
  221. LOAD(13); SHA_RND1(B,C,D,E,A,13);
  222. LOAD(14); SHA_RND1(A,B,C,D,E,14);
  223. LOAD(15); SHA_RND1(E,A,B,C,D,15);
  224. SHA_MIX( 0, 13, 8, 2); SHA_RND1(D,E,A,B,C, 0);
  225. SHA_MIX( 1, 14, 9, 3); SHA_RND1(C,D,E,A,B, 1);
  226. SHA_MIX( 2, 15, 10, 4); SHA_RND1(B,C,D,E,A, 2);
  227. SHA_MIX( 3, 0, 11, 5); SHA_RND1(A,B,C,D,E, 3);
  228. SHA_MIX( 4, 1, 12, 6); SHA_RND2(E,A,B,C,D, 4);
  229. SHA_MIX( 5, 2, 13, 7); SHA_RND2(D,E,A,B,C, 5);
  230. SHA_MIX( 6, 3, 14, 8); SHA_RND2(C,D,E,A,B, 6);
  231. SHA_MIX( 7, 4, 15, 9); SHA_RND2(B,C,D,E,A, 7);
  232. SHA_MIX( 8, 5, 0, 10); SHA_RND2(A,B,C,D,E, 8);
  233. SHA_MIX( 9, 6, 1, 11); SHA_RND2(E,A,B,C,D, 9);
  234. SHA_MIX(10, 7, 2, 12); SHA_RND2(D,E,A,B,C,10);
  235. SHA_MIX(11, 8, 3, 13); SHA_RND2(C,D,E,A,B,11);
  236. SHA_MIX(12, 9, 4, 14); SHA_RND2(B,C,D,E,A,12);
  237. SHA_MIX(13, 10, 5, 15); SHA_RND2(A,B,C,D,E,13);
  238. SHA_MIX(14, 11, 6, 0); SHA_RND2(E,A,B,C,D,14);
  239. SHA_MIX(15, 12, 7, 1); SHA_RND2(D,E,A,B,C,15);
  240. SHA_MIX( 0, 13, 8, 2); SHA_RND2(C,D,E,A,B, 0);
  241. SHA_MIX( 1, 14, 9, 3); SHA_RND2(B,C,D,E,A, 1);
  242. SHA_MIX( 2, 15, 10, 4); SHA_RND2(A,B,C,D,E, 2);
  243. SHA_MIX( 3, 0, 11, 5); SHA_RND2(E,A,B,C,D, 3);
  244. SHA_MIX( 4, 1, 12, 6); SHA_RND2(D,E,A,B,C, 4);
  245. SHA_MIX( 5, 2, 13, 7); SHA_RND2(C,D,E,A,B, 5);
  246. SHA_MIX( 6, 3, 14, 8); SHA_RND2(B,C,D,E,A, 6);
  247. SHA_MIX( 7, 4, 15, 9); SHA_RND2(A,B,C,D,E, 7);
  248. SHA_MIX( 8, 5, 0, 10); SHA_RND3(E,A,B,C,D, 8);
  249. SHA_MIX( 9, 6, 1, 11); SHA_RND3(D,E,A,B,C, 9);
  250. SHA_MIX(10, 7, 2, 12); SHA_RND3(C,D,E,A,B,10);
  251. SHA_MIX(11, 8, 3, 13); SHA_RND3(B,C,D,E,A,11);
  252. SHA_MIX(12, 9, 4, 14); SHA_RND3(A,B,C,D,E,12);
  253. SHA_MIX(13, 10, 5, 15); SHA_RND3(E,A,B,C,D,13);
  254. SHA_MIX(14, 11, 6, 0); SHA_RND3(D,E,A,B,C,14);
  255. SHA_MIX(15, 12, 7, 1); SHA_RND3(C,D,E,A,B,15);
  256. SHA_MIX( 0, 13, 8, 2); SHA_RND3(B,C,D,E,A, 0);
  257. SHA_MIX( 1, 14, 9, 3); SHA_RND3(A,B,C,D,E, 1);
  258. SHA_MIX( 2, 15, 10, 4); SHA_RND3(E,A,B,C,D, 2);
  259. SHA_MIX( 3, 0, 11, 5); SHA_RND3(D,E,A,B,C, 3);
  260. SHA_MIX( 4, 1, 12, 6); SHA_RND3(C,D,E,A,B, 4);
  261. SHA_MIX( 5, 2, 13, 7); SHA_RND3(B,C,D,E,A, 5);
  262. SHA_MIX( 6, 3, 14, 8); SHA_RND3(A,B,C,D,E, 6);
  263. SHA_MIX( 7, 4, 15, 9); SHA_RND3(E,A,B,C,D, 7);
  264. SHA_MIX( 8, 5, 0, 10); SHA_RND3(D,E,A,B,C, 8);
  265. SHA_MIX( 9, 6, 1, 11); SHA_RND3(C,D,E,A,B, 9);
  266. SHA_MIX(10, 7, 2, 12); SHA_RND3(B,C,D,E,A,10);
  267. SHA_MIX(11, 8, 3, 13); SHA_RND3(A,B,C,D,E,11);
  268. SHA_MIX(12, 9, 4, 14); SHA_RND4(E,A,B,C,D,12);
  269. SHA_MIX(13, 10, 5, 15); SHA_RND4(D,E,A,B,C,13);
  270. SHA_MIX(14, 11, 6, 0); SHA_RND4(C,D,E,A,B,14);
  271. SHA_MIX(15, 12, 7, 1); SHA_RND4(B,C,D,E,A,15);
  272. SHA_MIX( 0, 13, 8, 2); SHA_RND4(A,B,C,D,E, 0);
  273. SHA_MIX( 1, 14, 9, 3); SHA_RND4(E,A,B,C,D, 1);
  274. SHA_MIX( 2, 15, 10, 4); SHA_RND4(D,E,A,B,C, 2);
  275. SHA_MIX( 3, 0, 11, 5); SHA_RND4(C,D,E,A,B, 3);
  276. SHA_MIX( 4, 1, 12, 6); SHA_RND4(B,C,D,E,A, 4);
  277. SHA_MIX( 5, 2, 13, 7); SHA_RND4(A,B,C,D,E, 5);
  278. SHA_MIX( 6, 3, 14, 8); SHA_RND4(E,A,B,C,D, 6);
  279. SHA_MIX( 7, 4, 15, 9); SHA_RND4(D,E,A,B,C, 7);
  280. SHA_MIX( 8, 5, 0, 10); SHA_RND4(C,D,E,A,B, 8);
  281. SHA_MIX( 9, 6, 1, 11); SHA_RND4(B,C,D,E,A, 9);
  282. SHA_MIX(10, 7, 2, 12); SHA_RND4(A,B,C,D,E,10);
  283. SHA_MIX(11, 8, 3, 13); SHA_RND4(E,A,B,C,D,11);
  284. SHA_MIX(12, 9, 4, 14); SHA_RND4(D,E,A,B,C,12);
  285. SHA_MIX(13, 10, 5, 15); SHA_RND4(C,D,E,A,B,13);
  286. SHA_MIX(14, 11, 6, 0); SHA_RND4(B,C,D,E,A,14);
  287. SHA_MIX(15, 12, 7, 1); SHA_RND4(A,B,C,D,E,15);
  288. XH(0) += A;
  289. XH(1) += B;
  290. XH(2) += C;
  291. XH(3) += D;
  292. XH(4) += E;
  293. }