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.

199 lines
5.2KB

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