SHA2.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /*
  2. * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
  3. * Copyright (c) 2023, Jelle Raaijmakers <jelle@gmta.nl>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/Types.h>
  8. #include <LibCrypto/Hash/SHA2.h>
  9. namespace Crypto::Hash {
  10. constexpr static auto ROTRIGHT(u32 a, size_t b) { return (a >> b) | (a << (32 - b)); }
  11. constexpr static auto CH(u32 x, u32 y, u32 z) { return (x & y) ^ (z & ~x); }
  12. constexpr static auto MAJ(u32 x, u32 y, u32 z) { return (x & y) ^ (x & z) ^ (y & z); }
  13. constexpr static auto EP0(u32 x) { return ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22); }
  14. constexpr static auto EP1(u32 x) { return ROTRIGHT(x, 6) ^ ROTRIGHT(x, 11) ^ ROTRIGHT(x, 25); }
  15. constexpr static auto SIGN0(u32 x) { return ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ (x >> 3); }
  16. constexpr static auto SIGN1(u32 x) { return ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ (x >> 10); }
  17. constexpr static auto ROTRIGHT(u64 a, size_t b) { return (a >> b) | (a << (64 - b)); }
  18. constexpr static auto CH(u64 x, u64 y, u64 z) { return (x & y) ^ (z & ~x); }
  19. constexpr static auto MAJ(u64 x, u64 y, u64 z) { return (x & y) ^ (x & z) ^ (y & z); }
  20. constexpr static auto EP0(u64 x) { return ROTRIGHT(x, 28) ^ ROTRIGHT(x, 34) ^ ROTRIGHT(x, 39); }
  21. constexpr static auto EP1(u64 x) { return ROTRIGHT(x, 14) ^ ROTRIGHT(x, 18) ^ ROTRIGHT(x, 41); }
  22. constexpr static auto SIGN0(u64 x) { return ROTRIGHT(x, 1) ^ ROTRIGHT(x, 8) ^ (x >> 7); }
  23. constexpr static auto SIGN1(u64 x) { return ROTRIGHT(x, 19) ^ ROTRIGHT(x, 61) ^ (x >> 6); }
  24. inline void SHA256::transform(u8 const* data)
  25. {
  26. u32 m[64];
  27. size_t i = 0;
  28. for (size_t j = 0; i < 16; ++i, j += 4) {
  29. m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | data[j + 3];
  30. }
  31. for (; i < BlockSize; ++i) {
  32. m[i] = SIGN1(m[i - 2]) + m[i - 7] + SIGN0(m[i - 15]) + m[i - 16];
  33. }
  34. auto a = m_state[0], b = m_state[1],
  35. c = m_state[2], d = m_state[3],
  36. e = m_state[4], f = m_state[5],
  37. g = m_state[6], h = m_state[7];
  38. for (i = 0; i < Rounds; ++i) {
  39. auto temp0 = h + EP1(e) + CH(e, f, g) + SHA256Constants::RoundConstants[i] + m[i];
  40. auto temp1 = EP0(a) + MAJ(a, b, c);
  41. h = g;
  42. g = f;
  43. f = e;
  44. e = d + temp0;
  45. d = c;
  46. c = b;
  47. b = a;
  48. a = temp0 + temp1;
  49. }
  50. m_state[0] += a;
  51. m_state[1] += b;
  52. m_state[2] += c;
  53. m_state[3] += d;
  54. m_state[4] += e;
  55. m_state[5] += f;
  56. m_state[6] += g;
  57. m_state[7] += h;
  58. }
  59. template<size_t BlockSize, typename Callback>
  60. void update_buffer(u8* buffer, u8 const* input, size_t length, size_t& data_length, Callback callback)
  61. {
  62. while (length > 0) {
  63. size_t copy_bytes = AK::min(length, BlockSize - data_length);
  64. __builtin_memcpy(buffer + data_length, input, copy_bytes);
  65. input += copy_bytes;
  66. length -= copy_bytes;
  67. data_length += copy_bytes;
  68. if (data_length == BlockSize) {
  69. callback();
  70. data_length = 0;
  71. }
  72. }
  73. }
  74. void SHA256::update(u8 const* message, size_t length)
  75. {
  76. update_buffer<BlockSize>(m_data_buffer, message, length, m_data_length, [&]() {
  77. transform(m_data_buffer);
  78. m_bit_length += BlockSize * 8;
  79. });
  80. }
  81. SHA256::DigestType SHA256::digest()
  82. {
  83. auto digest = peek();
  84. reset();
  85. return digest;
  86. }
  87. SHA256::DigestType SHA256::peek()
  88. {
  89. DigestType digest;
  90. size_t i = m_data_length;
  91. if (i < FinalBlockDataSize) {
  92. m_data_buffer[i++] = 0x80;
  93. while (i < FinalBlockDataSize)
  94. m_data_buffer[i++] = 0x00;
  95. } else {
  96. // First, complete a block with some padding.
  97. m_data_buffer[i++] = 0x80;
  98. while (i < BlockSize)
  99. m_data_buffer[i++] = 0x00;
  100. transform(m_data_buffer);
  101. // Then start another block with BlockSize - 8 bytes of zeros
  102. __builtin_memset(m_data_buffer, 0, FinalBlockDataSize);
  103. }
  104. // append total message length
  105. m_bit_length += m_data_length * 8;
  106. m_data_buffer[BlockSize - 1] = m_bit_length;
  107. m_data_buffer[BlockSize - 2] = m_bit_length >> 8;
  108. m_data_buffer[BlockSize - 3] = m_bit_length >> 16;
  109. m_data_buffer[BlockSize - 4] = m_bit_length >> 24;
  110. m_data_buffer[BlockSize - 5] = m_bit_length >> 32;
  111. m_data_buffer[BlockSize - 6] = m_bit_length >> 40;
  112. m_data_buffer[BlockSize - 7] = m_bit_length >> 48;
  113. m_data_buffer[BlockSize - 8] = m_bit_length >> 56;
  114. transform(m_data_buffer);
  115. // SHA uses big-endian and we assume little-endian
  116. // FIXME: looks like a thing for AK::NetworkOrdered,
  117. // but that doesn't support shifting operations
  118. for (i = 0; i < 4; ++i) {
  119. digest.data[i + 0] = (m_state[0] >> (24 - i * 8)) & 0x000000ff;
  120. digest.data[i + 4] = (m_state[1] >> (24 - i * 8)) & 0x000000ff;
  121. digest.data[i + 8] = (m_state[2] >> (24 - i * 8)) & 0x000000ff;
  122. digest.data[i + 12] = (m_state[3] >> (24 - i * 8)) & 0x000000ff;
  123. digest.data[i + 16] = (m_state[4] >> (24 - i * 8)) & 0x000000ff;
  124. digest.data[i + 20] = (m_state[5] >> (24 - i * 8)) & 0x000000ff;
  125. digest.data[i + 24] = (m_state[6] >> (24 - i * 8)) & 0x000000ff;
  126. digest.data[i + 28] = (m_state[7] >> (24 - i * 8)) & 0x000000ff;
  127. }
  128. return digest;
  129. }
  130. inline void SHA384::transform(u8 const* data)
  131. {
  132. u64 m[80];
  133. size_t i = 0;
  134. for (size_t j = 0; i < 16; ++i, j += 8) {
  135. m[i] = ((u64)data[j] << 56) | ((u64)data[j + 1] << 48) | ((u64)data[j + 2] << 40) | ((u64)data[j + 3] << 32) | ((u64)data[j + 4] << 24) | ((u64)data[j + 5] << 16) | ((u64)data[j + 6] << 8) | (u64)data[j + 7];
  136. }
  137. for (; i < Rounds; ++i) {
  138. m[i] = SIGN1(m[i - 2]) + m[i - 7] + SIGN0(m[i - 15]) + m[i - 16];
  139. }
  140. auto a = m_state[0], b = m_state[1],
  141. c = m_state[2], d = m_state[3],
  142. e = m_state[4], f = m_state[5],
  143. g = m_state[6], h = m_state[7];
  144. for (i = 0; i < Rounds; ++i) {
  145. // Note : SHA384 uses the SHA512 constants.
  146. auto temp0 = h + EP1(e) + CH(e, f, g) + SHA512Constants::RoundConstants[i] + m[i];
  147. auto temp1 = EP0(a) + MAJ(a, b, c);
  148. h = g;
  149. g = f;
  150. f = e;
  151. e = d + temp0;
  152. d = c;
  153. c = b;
  154. b = a;
  155. a = temp0 + temp1;
  156. }
  157. m_state[0] += a;
  158. m_state[1] += b;
  159. m_state[2] += c;
  160. m_state[3] += d;
  161. m_state[4] += e;
  162. m_state[5] += f;
  163. m_state[6] += g;
  164. m_state[7] += h;
  165. }
  166. void SHA384::update(u8 const* message, size_t length)
  167. {
  168. update_buffer<BlockSize>(m_data_buffer, message, length, m_data_length, [&]() {
  169. transform(m_data_buffer);
  170. m_bit_length += BlockSize * 8;
  171. });
  172. }
  173. SHA384::DigestType SHA384::digest()
  174. {
  175. auto digest = peek();
  176. reset();
  177. return digest;
  178. }
  179. SHA384::DigestType SHA384::peek()
  180. {
  181. DigestType digest;
  182. size_t i = m_data_length;
  183. if (i < FinalBlockDataSize) {
  184. m_data_buffer[i++] = 0x80;
  185. while (i < FinalBlockDataSize)
  186. m_data_buffer[i++] = 0x00;
  187. } else {
  188. // First, complete a block with some padding.
  189. m_data_buffer[i++] = 0x80;
  190. while (i < BlockSize)
  191. m_data_buffer[i++] = 0x00;
  192. transform(m_data_buffer);
  193. // Then start another block with BlockSize - 8 bytes of zeros
  194. __builtin_memset(m_data_buffer, 0, FinalBlockDataSize);
  195. }
  196. // append total message length
  197. m_bit_length += m_data_length * 8;
  198. m_data_buffer[BlockSize - 1] = m_bit_length;
  199. m_data_buffer[BlockSize - 2] = m_bit_length >> 8;
  200. m_data_buffer[BlockSize - 3] = m_bit_length >> 16;
  201. m_data_buffer[BlockSize - 4] = m_bit_length >> 24;
  202. m_data_buffer[BlockSize - 5] = m_bit_length >> 32;
  203. m_data_buffer[BlockSize - 6] = m_bit_length >> 40;
  204. m_data_buffer[BlockSize - 7] = m_bit_length >> 48;
  205. m_data_buffer[BlockSize - 8] = m_bit_length >> 56;
  206. // FIXME: Theoretically we should keep track of the number of bits as a u128, now we can only hash up to 2 EiB.
  207. m_data_buffer[BlockSize - 9] = 0;
  208. m_data_buffer[BlockSize - 10] = 0;
  209. m_data_buffer[BlockSize - 11] = 0;
  210. m_data_buffer[BlockSize - 12] = 0;
  211. m_data_buffer[BlockSize - 13] = 0;
  212. m_data_buffer[BlockSize - 14] = 0;
  213. m_data_buffer[BlockSize - 15] = 0;
  214. m_data_buffer[BlockSize - 16] = 0;
  215. transform(m_data_buffer);
  216. // SHA uses big-endian and we assume little-endian
  217. // FIXME: looks like a thing for AK::NetworkOrdered,
  218. // but that doesn't support shifting operations
  219. for (i = 0; i < 8; ++i) {
  220. digest.data[i + 0] = (m_state[0] >> (56 - i * 8)) & 0x000000ff;
  221. digest.data[i + 8] = (m_state[1] >> (56 - i * 8)) & 0x000000ff;
  222. digest.data[i + 16] = (m_state[2] >> (56 - i * 8)) & 0x000000ff;
  223. digest.data[i + 24] = (m_state[3] >> (56 - i * 8)) & 0x000000ff;
  224. digest.data[i + 32] = (m_state[4] >> (56 - i * 8)) & 0x000000ff;
  225. digest.data[i + 40] = (m_state[5] >> (56 - i * 8)) & 0x000000ff;
  226. }
  227. return digest;
  228. }
  229. inline void SHA512::transform(u8 const* data)
  230. {
  231. u64 m[80];
  232. size_t i = 0;
  233. for (size_t j = 0; i < 16; ++i, j += 8) {
  234. m[i] = ((u64)data[j] << 56) | ((u64)data[j + 1] << 48) | ((u64)data[j + 2] << 40) | ((u64)data[j + 3] << 32) | ((u64)data[j + 4] << 24) | ((u64)data[j + 5] << 16) | ((u64)data[j + 6] << 8) | (u64)data[j + 7];
  235. }
  236. for (; i < Rounds; ++i) {
  237. m[i] = SIGN1(m[i - 2]) + m[i - 7] + SIGN0(m[i - 15]) + m[i - 16];
  238. }
  239. auto a = m_state[0], b = m_state[1],
  240. c = m_state[2], d = m_state[3],
  241. e = m_state[4], f = m_state[5],
  242. g = m_state[6], h = m_state[7];
  243. for (i = 0; i < Rounds; ++i) {
  244. auto temp0 = h + EP1(e) + CH(e, f, g) + SHA512Constants::RoundConstants[i] + m[i];
  245. auto temp1 = EP0(a) + MAJ(a, b, c);
  246. h = g;
  247. g = f;
  248. f = e;
  249. e = d + temp0;
  250. d = c;
  251. c = b;
  252. b = a;
  253. a = temp0 + temp1;
  254. }
  255. m_state[0] += a;
  256. m_state[1] += b;
  257. m_state[2] += c;
  258. m_state[3] += d;
  259. m_state[4] += e;
  260. m_state[5] += f;
  261. m_state[6] += g;
  262. m_state[7] += h;
  263. }
  264. void SHA512::update(u8 const* message, size_t length)
  265. {
  266. update_buffer<BlockSize>(m_data_buffer, message, length, m_data_length, [&]() {
  267. transform(m_data_buffer);
  268. m_bit_length += BlockSize * 8;
  269. });
  270. }
  271. SHA512::DigestType SHA512::digest()
  272. {
  273. auto digest = peek();
  274. reset();
  275. return digest;
  276. }
  277. SHA512::DigestType SHA512::peek()
  278. {
  279. DigestType digest;
  280. size_t i = m_data_length;
  281. if (i < FinalBlockDataSize) {
  282. m_data_buffer[i++] = 0x80;
  283. while (i < FinalBlockDataSize)
  284. m_data_buffer[i++] = 0x00;
  285. } else {
  286. // First, complete a block with some padding.
  287. m_data_buffer[i++] = 0x80;
  288. while (i < BlockSize)
  289. m_data_buffer[i++] = 0x00;
  290. transform(m_data_buffer);
  291. // Then start another block with BlockSize - 8 bytes of zeros
  292. __builtin_memset(m_data_buffer, 0, FinalBlockDataSize);
  293. }
  294. // append total message length
  295. m_bit_length += m_data_length * 8;
  296. m_data_buffer[BlockSize - 1] = m_bit_length;
  297. m_data_buffer[BlockSize - 2] = m_bit_length >> 8;
  298. m_data_buffer[BlockSize - 3] = m_bit_length >> 16;
  299. m_data_buffer[BlockSize - 4] = m_bit_length >> 24;
  300. m_data_buffer[BlockSize - 5] = m_bit_length >> 32;
  301. m_data_buffer[BlockSize - 6] = m_bit_length >> 40;
  302. m_data_buffer[BlockSize - 7] = m_bit_length >> 48;
  303. m_data_buffer[BlockSize - 8] = m_bit_length >> 56;
  304. // FIXME: Theoretically we should keep track of the number of bits as a u128, now we can only hash up to 2 EiB.
  305. m_data_buffer[BlockSize - 9] = 0;
  306. m_data_buffer[BlockSize - 10] = 0;
  307. m_data_buffer[BlockSize - 11] = 0;
  308. m_data_buffer[BlockSize - 12] = 0;
  309. m_data_buffer[BlockSize - 13] = 0;
  310. m_data_buffer[BlockSize - 14] = 0;
  311. m_data_buffer[BlockSize - 15] = 0;
  312. m_data_buffer[BlockSize - 16] = 0;
  313. transform(m_data_buffer);
  314. // SHA uses big-endian and we assume little-endian
  315. // FIXME: looks like a thing for AK::NetworkOrdered,
  316. // but that doesn't support shifting operations
  317. for (i = 0; i < 8; ++i) {
  318. digest.data[i + 0] = (m_state[0] >> (56 - i * 8)) & 0x000000ff;
  319. digest.data[i + 8] = (m_state[1] >> (56 - i * 8)) & 0x000000ff;
  320. digest.data[i + 16] = (m_state[2] >> (56 - i * 8)) & 0x000000ff;
  321. digest.data[i + 24] = (m_state[3] >> (56 - i * 8)) & 0x000000ff;
  322. digest.data[i + 32] = (m_state[4] >> (56 - i * 8)) & 0x000000ff;
  323. digest.data[i + 40] = (m_state[5] >> (56 - i * 8)) & 0x000000ff;
  324. digest.data[i + 48] = (m_state[6] >> (56 - i * 8)) & 0x000000ff;
  325. digest.data[i + 56] = (m_state[7] >> (56 - i * 8)) & 0x000000ff;
  326. }
  327. return digest;
  328. }
  329. }