sha1.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * SHA-1 hash in C
  3. *
  4. * Copyright (c) 2014 Project Nayuki
  5. * https://www.nayuki.io/page/fast-sha1-hash-implementation-in-x86-assembly
  6. *
  7. * (MIT License)
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  9. * this software and associated documentation files (the "Software"), to deal in
  10. * the Software without restriction, including without limitation the rights to
  11. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  12. * the Software, and to permit persons to whom the Software is furnished to do so,
  13. * subject to the following conditions:
  14. * - The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. * - The Software is provided "as is", without warranty of any kind, express or
  17. * implied, including but not limited to the warranties of merchantability,
  18. * fitness for a particular purpose and noninfringement. In no event shall the
  19. * authors or copyright holders be liable for any claim, damages or other
  20. * liability, whether in an action of contract, tort or otherwise, arising from,
  21. * out of or in connection with the Software or the use or other dealings in the
  22. * Software.
  23. */
  24. #include <stddef.h>
  25. #include <stdint.h>
  26. #include <string.h>
  27. void sha1_compress(uint32_t state[5], const uint8_t block[64]) {
  28. #define ROTL32(x, n) (((0U + (x)) << (n)) | ((x) >> (32 - (n)))) // Assumes that x is uint32_t and 0 < n < 32
  29. #define LOADSCHEDULE(i) \
  30. schedule[i] = (uint32_t)block[i * 4 + 0] << 24 \
  31. | (uint32_t)block[i * 4 + 1] << 16 \
  32. | (uint32_t)block[i * 4 + 2] << 8 \
  33. | (uint32_t)block[i * 4 + 3] << 0;
  34. #define SCHEDULE(i) \
  35. temp = schedule[(i - 3) & 0xF] ^ schedule[(i - 8) & 0xF] ^ schedule[(i - 14) & 0xF] ^ schedule[(i - 16) & 0xF]; \
  36. schedule[i & 0xF] = ROTL32(temp, 1);
  37. #define ROUND0a(a, b, c, d, e, i) LOADSCHEDULE(i) ROUNDTAIL(a, b, e, ((b & c) | (~b & d)) , i, 0x5A827999)
  38. #define ROUND0b(a, b, c, d, e, i) SCHEDULE(i) ROUNDTAIL(a, b, e, ((b & c) | (~b & d)) , i, 0x5A827999)
  39. #define ROUND1(a, b, c, d, e, i) SCHEDULE(i) ROUNDTAIL(a, b, e, (b ^ c ^ d) , i, 0x6ED9EBA1)
  40. #define ROUND2(a, b, c, d, e, i) SCHEDULE(i) ROUNDTAIL(a, b, e, ((b & c) ^ (b & d) ^ (c & d)), i, 0x8F1BBCDC)
  41. #define ROUND3(a, b, c, d, e, i) SCHEDULE(i) ROUNDTAIL(a, b, e, (b ^ c ^ d) , i, 0xCA62C1D6)
  42. #define ROUNDTAIL(a, b, e, f, i, k) \
  43. e = 0U + e + ROTL32(a, 5) + f + UINT32_C(k) + schedule[i & 0xF]; \
  44. b = ROTL32(b, 30);
  45. uint32_t a = state[0];
  46. uint32_t b = state[1];
  47. uint32_t c = state[2];
  48. uint32_t d = state[3];
  49. uint32_t e = state[4];
  50. uint32_t schedule[16];
  51. uint32_t temp;
  52. ROUND0a(a, b, c, d, e, 0)
  53. ROUND0a(e, a, b, c, d, 1)
  54. ROUND0a(d, e, a, b, c, 2)
  55. ROUND0a(c, d, e, a, b, 3)
  56. ROUND0a(b, c, d, e, a, 4)
  57. ROUND0a(a, b, c, d, e, 5)
  58. ROUND0a(e, a, b, c, d, 6)
  59. ROUND0a(d, e, a, b, c, 7)
  60. ROUND0a(c, d, e, a, b, 8)
  61. ROUND0a(b, c, d, e, a, 9)
  62. ROUND0a(a, b, c, d, e, 10)
  63. ROUND0a(e, a, b, c, d, 11)
  64. ROUND0a(d, e, a, b, c, 12)
  65. ROUND0a(c, d, e, a, b, 13)
  66. ROUND0a(b, c, d, e, a, 14)
  67. ROUND0a(a, b, c, d, e, 15)
  68. ROUND0b(e, a, b, c, d, 16)
  69. ROUND0b(d, e, a, b, c, 17)
  70. ROUND0b(c, d, e, a, b, 18)
  71. ROUND0b(b, c, d, e, a, 19)
  72. ROUND1(a, b, c, d, e, 20)
  73. ROUND1(e, a, b, c, d, 21)
  74. ROUND1(d, e, a, b, c, 22)
  75. ROUND1(c, d, e, a, b, 23)
  76. ROUND1(b, c, d, e, a, 24)
  77. ROUND1(a, b, c, d, e, 25)
  78. ROUND1(e, a, b, c, d, 26)
  79. ROUND1(d, e, a, b, c, 27)
  80. ROUND1(c, d, e, a, b, 28)
  81. ROUND1(b, c, d, e, a, 29)
  82. ROUND1(a, b, c, d, e, 30)
  83. ROUND1(e, a, b, c, d, 31)
  84. ROUND1(d, e, a, b, c, 32)
  85. ROUND1(c, d, e, a, b, 33)
  86. ROUND1(b, c, d, e, a, 34)
  87. ROUND1(a, b, c, d, e, 35)
  88. ROUND1(e, a, b, c, d, 36)
  89. ROUND1(d, e, a, b, c, 37)
  90. ROUND1(c, d, e, a, b, 38)
  91. ROUND1(b, c, d, e, a, 39)
  92. ROUND2(a, b, c, d, e, 40)
  93. ROUND2(e, a, b, c, d, 41)
  94. ROUND2(d, e, a, b, c, 42)
  95. ROUND2(c, d, e, a, b, 43)
  96. ROUND2(b, c, d, e, a, 44)
  97. ROUND2(a, b, c, d, e, 45)
  98. ROUND2(e, a, b, c, d, 46)
  99. ROUND2(d, e, a, b, c, 47)
  100. ROUND2(c, d, e, a, b, 48)
  101. ROUND2(b, c, d, e, a, 49)
  102. ROUND2(a, b, c, d, e, 50)
  103. ROUND2(e, a, b, c, d, 51)
  104. ROUND2(d, e, a, b, c, 52)
  105. ROUND2(c, d, e, a, b, 53)
  106. ROUND2(b, c, d, e, a, 54)
  107. ROUND2(a, b, c, d, e, 55)
  108. ROUND2(e, a, b, c, d, 56)
  109. ROUND2(d, e, a, b, c, 57)
  110. ROUND2(c, d, e, a, b, 58)
  111. ROUND2(b, c, d, e, a, 59)
  112. ROUND3(a, b, c, d, e, 60)
  113. ROUND3(e, a, b, c, d, 61)
  114. ROUND3(d, e, a, b, c, 62)
  115. ROUND3(c, d, e, a, b, 63)
  116. ROUND3(b, c, d, e, a, 64)
  117. ROUND3(a, b, c, d, e, 65)
  118. ROUND3(e, a, b, c, d, 66)
  119. ROUND3(d, e, a, b, c, 67)
  120. ROUND3(c, d, e, a, b, 68)
  121. ROUND3(b, c, d, e, a, 69)
  122. ROUND3(a, b, c, d, e, 70)
  123. ROUND3(e, a, b, c, d, 71)
  124. ROUND3(d, e, a, b, c, 72)
  125. ROUND3(c, d, e, a, b, 73)
  126. ROUND3(b, c, d, e, a, 74)
  127. ROUND3(a, b, c, d, e, 75)
  128. ROUND3(e, a, b, c, d, 76)
  129. ROUND3(d, e, a, b, c, 77)
  130. ROUND3(c, d, e, a, b, 78)
  131. ROUND3(b, c, d, e, a, 79)
  132. state[0] = 0U + state[0] + a;
  133. state[1] = 0U + state[1] + b;
  134. state[2] = 0U + state[2] + c;
  135. state[3] = 0U + state[3] + d;
  136. state[4] = 0U + state[4] + e;
  137. }
  138. void sha1_hash(const uint8_t *message, size_t len, uint32_t hash[5]) {
  139. hash[0] = UINT32_C(0x67452301);
  140. hash[1] = UINT32_C(0xEFCDAB89);
  141. hash[2] = UINT32_C(0x98BADCFE);
  142. hash[3] = UINT32_C(0x10325476);
  143. hash[4] = UINT32_C(0xC3D2E1F0);
  144. #define BLOCK_SIZE 64 // In bytes
  145. #define LENGTH_SIZE 8 // In bytes
  146. size_t off;
  147. for (off = 0; len - off >= BLOCK_SIZE; off += BLOCK_SIZE)
  148. sha1_compress(hash, &message[off]);
  149. uint8_t block[BLOCK_SIZE] = { 0 };
  150. size_t rem = len - off;
  151. memcpy(block, &message[off], rem);
  152. block[rem] = 0x80;
  153. rem++;
  154. if (BLOCK_SIZE - rem < LENGTH_SIZE) {
  155. sha1_compress(hash, block);
  156. memset(block, 0, sizeof(block));
  157. }
  158. block[BLOCK_SIZE - 1] = (uint8_t)((len & 0x1FU) << 3);
  159. len >>= 5;
  160. int i;
  161. for (i = 1; i < LENGTH_SIZE; i++, len >>= 8)
  162. block[BLOCK_SIZE - 1 - i] = (uint8_t)(len & 0xFFU);
  163. sha1_compress(hash, block);
  164. }