Audio plugin host https://kx.studio/carla
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.

CarlaSha1Utils.hpp 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * Carla sha1 utils
  3. * Copyright (C) 2023 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_SHA1_UTILS_HPP_INCLUDED
  18. #define CARLA_SHA1_UTILS_HPP_INCLUDED
  19. #include "CarlaUtils.hpp"
  20. #ifdef __BIG_ENDIAN__
  21. # define CARLA_SHA1_BIG_ENDIAN
  22. #elif defined __LITTLE_ENDIAN__
  23. /* override */
  24. #elif defined __BYTE_ORDER
  25. # if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  26. # define CARLA_SHA1_BIG_ENDIAN
  27. # endif
  28. #else // ! defined __LITTLE_ENDIAN__
  29. # include <endian.h> // machine/endian.h
  30. # if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  31. # define CARLA_SHA1_BIG_ENDIAN
  32. # endif
  33. #endif
  34. /*!
  35. * Simple, single-use SHA1 class.
  36. * Must be discarded after use.
  37. *
  38. * Based on libcrypt by Wei Dai and other contributors (originally in the public domain)
  39. */
  40. class CarlaSha1 {
  41. static constexpr const size_t BLOCK_LENGTH = 64;
  42. union {
  43. uint8_t u8[BLOCK_LENGTH];
  44. uint32_t u32[BLOCK_LENGTH/sizeof(uint32_t)];
  45. } buffer;
  46. uint32_t state[5];
  47. uint32_t byteCount;
  48. uint8_t bufferOffset;
  49. char resultstr[41];
  50. static_assert(sizeof(buffer.u8) == sizeof(buffer.u32), "valid size");
  51. public:
  52. /*
  53. * Constructor.
  54. */
  55. CarlaSha1() noexcept
  56. : byteCount(0),
  57. bufferOffset(0)
  58. {
  59. state[0] = 0x67452301;
  60. state[1] = 0xefcdab89;
  61. state[2] = 0x98badcfe;
  62. state[3] = 0x10325476;
  63. state[4] = 0xc3d2e1f0;
  64. }
  65. /*
  66. * Write a single byte of data.
  67. */
  68. void writeByte(const uint8_t data) noexcept
  69. {
  70. ++byteCount;
  71. _addUncounted(data);
  72. }
  73. /*
  74. * Write a custom blob of data.
  75. */
  76. void write(const void* const data, size_t len) noexcept
  77. {
  78. const uint8_t* u8data = static_cast<const uint8_t*>(data);
  79. while (len--)
  80. writeByte(*u8data++);
  81. }
  82. /*
  83. * Return hash result as byte array (20 characters).
  84. * @note must be called only once!
  85. */
  86. const uint8_t* resultAsHash() noexcept
  87. {
  88. // Pad to complete the last block
  89. _pad();
  90. #ifndef CARLA_SHA1_BIG_ENDIAN
  91. // Swap byte order back
  92. for (int i=0; i<5; ++i)
  93. {
  94. state[i] = ((state[i] << 24) & 0xff000000)
  95. | ((state[i] << 8) & 0x00ff0000)
  96. | ((state[i] >> 8) & 0x0000ff00)
  97. | ((state[i] >> 24) & 0x000000ff);
  98. }
  99. #endif
  100. return static_cast<uint8_t*>(static_cast<void*>(state));
  101. }
  102. /*
  103. * Return hash result as null-terminated string.
  104. * @note must be called only once!
  105. */
  106. const char* resultAsString() noexcept
  107. {
  108. const uint8_t* const hash = resultAsHash();
  109. for (int i=0; i<20; ++i)
  110. std::snprintf(resultstr + (i * 2), 3, "%02x", hash[i]);
  111. resultstr[40] = '\0';
  112. return resultstr;
  113. }
  114. private:
  115. void _addUncounted(const uint8_t data) noexcept
  116. {
  117. #ifdef CARLA_SHA1_BIG_ENDIAN
  118. buffer.u8[bufferOffset] = data;
  119. #else
  120. buffer.u8[bufferOffset ^ 3] = data;
  121. #endif
  122. if (++bufferOffset == BLOCK_LENGTH)
  123. {
  124. bufferOffset = 0;
  125. _hashBlock();
  126. }
  127. }
  128. void _hashBlock() noexcept
  129. {
  130. uint32_t a = state[0];
  131. uint32_t b = state[1];
  132. uint32_t c = state[2];
  133. uint32_t d = state[3];
  134. uint32_t e = state[4];
  135. uint32_t t;
  136. for (uint8_t i=0; i<80; ++i)
  137. {
  138. if (i >= 16)
  139. {
  140. t = buffer.u32[(i + 13) & 15]
  141. ^ buffer.u32[(i + 8) & 15]
  142. ^ buffer.u32[(i + 2) & 15]
  143. ^ buffer.u32[i & 15];
  144. buffer.u32[i & 15] = _rol32(t, 1);
  145. }
  146. if (i < 20)
  147. {
  148. t = (d ^ (b & (c ^ d))) + 0x5a827999;
  149. }
  150. else if (i < 40)
  151. {
  152. t = (b ^ c ^ d) + 0x6ed9eba1;
  153. }
  154. else if (i < 60)
  155. {
  156. t = ((b & c) | (d & (b | c))) + 0x8f1bbcdc;
  157. }
  158. else
  159. {
  160. t = (b ^ c ^ d) + 0xca62c1d6;
  161. }
  162. t += _rol32(a, 5) + e + buffer.u32[i & 15];
  163. e = d;
  164. d = c;
  165. c = _rol32(b, 30);
  166. b = a;
  167. a = t;
  168. }
  169. state[0] += a;
  170. state[1] += b;
  171. state[2] += c;
  172. state[3] += d;
  173. state[4] += e;
  174. }
  175. // Implement SHA-1 padding (fips180-2 ยง5.1.1)
  176. void _pad() noexcept
  177. {
  178. // Pad with 0x80 followed by 0x00 until the end of the block
  179. _addUncounted(0x80);
  180. while (bufferOffset != 56) _addUncounted(0x00);
  181. // Append length in the last 8 bytes
  182. _addUncounted(0); // We're only using 32 bit lengths
  183. _addUncounted(0); // But SHA-1 supports 64 bit lengths
  184. _addUncounted(0); // So zero pad the top bits
  185. _addUncounted(byteCount >> 29); // Shifting to multiply by 8
  186. _addUncounted(byteCount >> 21); // as SHA-1 supports bitstreams as well as
  187. _addUncounted(byteCount >> 13); // byte.
  188. _addUncounted(byteCount >> 5);
  189. _addUncounted(byteCount << 3);
  190. }
  191. static uint32_t _rol32(const uint32_t number, const uint8_t bits) noexcept
  192. {
  193. return (number << bits) | (number >> (32 - bits));
  194. }
  195. };
  196. #endif // CARLA_SHA1_UTILS_HPP_INCLUDED