Utils.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2024-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #ifndef ZT_UTILS_HPP
  14. #define ZT_UTILS_HPP
  15. #include "Constants.hpp"
  16. #if __BYTE_ORDER == __LITTLE_ENDIAN
  17. #define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)((uint16_t)((uint16_t)(x) << 8U) | (uint16_t)((uint16_t)(x) >> 8U)))
  18. #else
  19. #define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)(x))
  20. #endif
  21. namespace ZeroTier {
  22. namespace Utils {
  23. #ifdef ZT_ARCH_X64
  24. struct CPUIDRegisters
  25. {
  26. uint32_t eax,ebx,ecx,edx;
  27. bool rdrand;
  28. bool aes;
  29. CPUIDRegisters();
  30. };
  31. extern const CPUIDRegisters CPUID;
  32. #endif
  33. /**
  34. * 256 zero bits / 32 zero bytes
  35. */
  36. extern const uint64_t ZERO256[4];
  37. /**
  38. * Hexadecimal characters 0-f
  39. */
  40. extern const char HEXCHARS[16];
  41. /**
  42. * Perform a time-invariant binary comparison
  43. *
  44. * @param a First binary string
  45. * @param b Second binary string
  46. * @param len Length of strings
  47. * @return True if strings are equal
  48. */
  49. bool secureEq(const void *a,const void *b,unsigned int len) noexcept;
  50. /**
  51. * Be absolutely sure to zero memory
  52. *
  53. * This uses some hacks to be totally sure the compiler does not optimize it out.
  54. *
  55. * @param ptr Memory to zero
  56. * @param len Length of memory in bytes
  57. */
  58. void burn(void *ptr,unsigned int len);
  59. /**
  60. * @param n Number to convert
  61. * @param s Buffer, at least 24 bytes in size
  62. * @return String containing 'n' in base 10 form
  63. */
  64. char *decimal(unsigned long n,char s[24]) noexcept;
  65. /**
  66. * Convert an unsigned integer into hex
  67. *
  68. * @param i Any unsigned integer
  69. * @param s Buffer to receive hex, must be at least (2*sizeof(i))+1 in size or overflow will occur.
  70. * @return Pointer to s containing hex string with trailing zero byte
  71. */
  72. char *hex(uint8_t i,char s[3]) noexcept;
  73. /**
  74. * Convert an unsigned integer into hex
  75. *
  76. * @param i Any unsigned integer
  77. * @param s Buffer to receive hex, must be at least (2*sizeof(i))+1 in size or overflow will occur.
  78. * @return Pointer to s containing hex string with trailing zero byte
  79. */
  80. char *hex(uint16_t i,char s[5]) noexcept;
  81. /**
  82. * Convert an unsigned integer into hex
  83. *
  84. * @param i Any unsigned integer
  85. * @param s Buffer to receive hex, must be at least (2*sizeof(i))+1 in size or overflow will occur.
  86. * @return Pointer to s containing hex string with trailing zero byte
  87. */
  88. char *hex(uint32_t i,char s[9]) noexcept;
  89. /**
  90. * Convert an unsigned integer into hex
  91. *
  92. * @param i Any unsigned integer
  93. * @param s Buffer to receive hex, must be at least (2*sizeof(i))+1 in size or overflow will occur.
  94. * @return Pointer to s containing hex string with trailing zero byte
  95. */
  96. char *hex(uint64_t i,char s[17]) noexcept;
  97. /**
  98. * Decode an unsigned integer in hex format
  99. *
  100. * @param s String to decode, non-hex chars are ignored
  101. * @return Unsigned integer
  102. */
  103. uint64_t unhex(const char *s) noexcept;
  104. /**
  105. * Convert a byte array into hex
  106. *
  107. * @param d Bytes
  108. * @param l Length of bytes
  109. * @param s String buffer, must be at least (l*2)+1 in size or overflow will occur
  110. * @return Pointer to filled string buffer
  111. */
  112. char *hex(const void *d,unsigned int l,char *s) noexcept;
  113. /**
  114. * Decode a hex string
  115. *
  116. * @param h Hex C-string (non hex chars are ignored)
  117. * @param hlen Maximum length of string (will stop at terminating zero)
  118. * @param buf Output buffer
  119. * @param buflen Length of output buffer
  120. * @return Number of written bytes
  121. */
  122. unsigned int unhex(const char *h,unsigned int hlen,void *buf,unsigned int buflen) noexcept;
  123. /**
  124. * Generate secure random bytes
  125. *
  126. * This will try to use whatever OS sources of entropy are available. It's
  127. * guarded by an internal mutex so it's thread-safe.
  128. *
  129. * @param buf Buffer to fill
  130. * @param bytes Number of random bytes to generate
  131. */
  132. void getSecureRandom(void *buf,unsigned int bytes) noexcept;
  133. /**
  134. * @return Secure random 64-bit integer
  135. */
  136. uint64_t getSecureRandomU64() noexcept;
  137. /**
  138. * Encode string to base32
  139. *
  140. * @param data Binary data to encode
  141. * @param length Length of data in bytes
  142. * @param result Result buffer
  143. * @param bufSize Size of result buffer
  144. * @return Number of bytes written
  145. */
  146. int b32e(const uint8_t *data,int length,char *result,int bufSize) noexcept;
  147. /**
  148. * Decode base32 string
  149. *
  150. * @param encoded C-string in base32 format (non-base32 characters are ignored)
  151. * @param result Result buffer
  152. * @param bufSize Size of result buffer
  153. * @return Number of bytes written or -1 on error
  154. */
  155. int b32d(const char *encoded, uint8_t *result, int bufSize) noexcept;
  156. /**
  157. * Get a non-cryptographic random integer
  158. */
  159. uint64_t random() noexcept;
  160. /**
  161. * Perform a safe C string copy, ALWAYS null-terminating the result
  162. *
  163. * This will never ever EVER result in dest[] not being null-terminated
  164. * regardless of any input parameter (other than len==0 which is invalid).
  165. *
  166. * @param dest Destination buffer (must not be NULL)
  167. * @param len Length of dest[] (if zero, false is returned and nothing happens)
  168. * @param src Source string (if NULL, dest will receive a zero-length string and true is returned)
  169. * @return True on success, false on overflow (buffer will still be 0-terminated)
  170. */
  171. bool scopy(char *dest,unsigned int len,const char *src) noexcept;
  172. /**
  173. * Mix bits in a 64-bit integer (non-cryptographic)
  174. *
  175. * https://nullprogram.com/blog/2018/07/31/
  176. *
  177. * @param x Integer to mix
  178. * @return Hashed value
  179. */
  180. static ZT_INLINE uint64_t hash64(uint64_t x) noexcept
  181. {
  182. x ^= x >> 30U;
  183. x *= 0xbf58476d1ce4e5b9ULL;
  184. x ^= x >> 27U;
  185. x *= 0x94d049bb133111ebULL;
  186. x ^= x >> 31U;
  187. return x;
  188. }
  189. /**
  190. * Check if a buffer's contents are all zero
  191. */
  192. static ZT_INLINE bool allZero(const void *const b,unsigned int l) noexcept
  193. {
  194. for(unsigned int i=0;i<l;++i) {
  195. if (reinterpret_cast<const uint8_t *>(b)[i] != 0)
  196. return false;
  197. }
  198. return true;
  199. }
  200. /**
  201. * Wrapper around reentrant strtok functions, which differ in name by platform
  202. *
  203. * @param str String to tokenize or NULL for subsequent calls
  204. * @param delim Delimiter
  205. * @param saveptr Pointer to pointer where function can save state
  206. * @return Next token or NULL if none
  207. */
  208. static ZT_INLINE char *stok(char *str,const char *delim,char **saveptr) noexcept
  209. {
  210. #ifdef __WINDOWS__
  211. return strtok_s(str,delim,saveptr);
  212. #else
  213. return strtok_r(str,delim,saveptr);
  214. #endif
  215. }
  216. static ZT_INLINE unsigned int strToUInt(const char *s) noexcept
  217. {
  218. return (unsigned int)strtoul(s,nullptr,10);
  219. }
  220. static ZT_INLINE unsigned long long hexStrToU64(const char *s) noexcept
  221. {
  222. #ifdef __WINDOWS__
  223. return (unsigned long long)_strtoui64(s,nullptr,16);
  224. #else
  225. return strtoull(s,nullptr,16);
  226. #endif
  227. }
  228. /**
  229. * Compute 32-bit FNV-1a checksum
  230. *
  231. * See: http://www.isthe.com/chongo/tech/comp/fnv/
  232. *
  233. * @param data Data to checksum
  234. * @param len Length of data
  235. * @return FNV1a checksum
  236. */
  237. static ZT_INLINE uint32_t fnv1a32(const void *const data,const unsigned int len) noexcept
  238. {
  239. uint32_t h = 0x811c9dc5;
  240. const uint32_t p = 0x01000193;
  241. for(unsigned int i=0;i<len;++i)
  242. h = (h ^ (uint32_t)reinterpret_cast<const uint8_t *>(data)[i]) * p;
  243. return h;
  244. }
  245. #ifdef __GNUC__
  246. static ZT_INLINE unsigned int countBits(const uint8_t v) noexcept { return (unsigned int)__builtin_popcount((unsigned int)v); }
  247. static ZT_INLINE unsigned int countBits(const uint16_t v) noexcept { return (unsigned int)__builtin_popcount((unsigned int)v); }
  248. static ZT_INLINE unsigned int countBits(const uint32_t v) noexcept { return (unsigned int)__builtin_popcountl((unsigned long)v); }
  249. static ZT_INLINE unsigned int countBits(const uint64_t v) noexcept{ return (unsigned int)__builtin_popcountll((unsigned long long)v); }
  250. #else
  251. template<typename T>
  252. static ZT_INLINE unsigned int countBits(T v) noexcept
  253. {
  254. v = v - ((v >> 1) & (T)~(T)0/3);
  255. v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);
  256. v = (v + (v >> 4)) & (T)~(T)0/255*15;
  257. return (unsigned int)((v * ((~((T)0))/((T)255))) >> ((sizeof(T) - 1) * 8));
  258. }
  259. #endif
  260. /**
  261. * Unconditionally swap bytes regardless of host byte order
  262. *
  263. * @param n Integer to swap
  264. * @return Integer with bytes reversed
  265. */
  266. static ZT_INLINE uint64_t swapBytes(const uint64_t n) noexcept
  267. {
  268. #ifdef __GNUC__
  269. return __builtin_bswap64(n);
  270. #else
  271. #ifdef _MSC_VER
  272. return (uint64_t)_byteswap_uint64((unsigned __int64)n);
  273. #else
  274. return (
  275. ((n & 0x00000000000000ffULL) << 56) |
  276. ((n & 0x000000000000ff00ULL) << 40) |
  277. ((n & 0x0000000000ff0000ULL) << 24) |
  278. ((n & 0x00000000ff000000ULL) << 8) |
  279. ((n & 0x000000ff00000000ULL) >> 8) |
  280. ((n & 0x0000ff0000000000ULL) >> 24) |
  281. ((n & 0x00ff000000000000ULL) >> 40) |
  282. ((n & 0xff00000000000000ULL) >> 56)
  283. );
  284. #endif
  285. #endif
  286. }
  287. /**
  288. * Unconditionally swap bytes regardless of host byte order
  289. *
  290. * @param n Integer to swap
  291. * @return Integer with bytes reversed
  292. */
  293. static ZT_INLINE uint32_t swapBytes(const uint32_t n) noexcept
  294. {
  295. #if defined(__GNUC__)
  296. return __builtin_bswap32(n);
  297. #else
  298. #ifdef _MSC_VER
  299. return (uint32_t)_byteswap_ulong((unsigned long)n);
  300. #else
  301. return htonl(n);
  302. #endif
  303. #endif
  304. }
  305. /**
  306. * Unconditionally swap bytes regardless of host byte order
  307. *
  308. * @param n Integer to swap
  309. * @return Integer with bytes reversed
  310. */
  311. static ZT_INLINE uint16_t swapBytes(const uint16_t n) noexcept
  312. {
  313. #if defined(__GNUC__)
  314. return __builtin_bswap16(n);
  315. #else
  316. #ifdef _MSC_VER
  317. return (uint16_t)_byteswap_ushort((unsigned short)n);
  318. #else
  319. return htons(n);
  320. #endif
  321. #endif
  322. }
  323. // These are helper adapters to load and swap integer types special cased by size
  324. // to work with all typedef'd variants, signed/unsigned, etc.
  325. template<typename I,unsigned int S>
  326. class _swap_bytes_bysize;
  327. template<typename I>
  328. class _swap_bytes_bysize<I,1> { public: static ZT_INLINE I s(const I n) noexcept { return n; } };
  329. template<typename I>
  330. class _swap_bytes_bysize<I,2> { public: static ZT_INLINE I s(const I n) noexcept { return (I)swapBytes((uint16_t)n); } };
  331. template<typename I>
  332. class _swap_bytes_bysize<I,4> { public: static ZT_INLINE I s(const I n) noexcept { return (I)swapBytes((uint32_t)n); } };
  333. template<typename I>
  334. class _swap_bytes_bysize<I,8> { public: static ZT_INLINE I s(const I n) noexcept { return (I)swapBytes((uint64_t)n); } };
  335. template<typename I,unsigned int S>
  336. class _load_be_bysize;
  337. template<typename I>
  338. class _load_be_bysize<I,1> { public: static ZT_INLINE I l(const uint8_t *const p) noexcept { return p[0]; }};
  339. template<typename I>
  340. class _load_be_bysize<I,2> { public: static ZT_INLINE I l(const uint8_t *const p) noexcept { return (I)(((unsigned int)p[0] << 8U) | (unsigned int)p[1]); }};
  341. template<typename I>
  342. class _load_be_bysize<I,4> { public: static ZT_INLINE I l(const uint8_t *const p) noexcept { return (I)(((uint32_t)p[0] << 24U) | ((uint32_t)p[1] << 16U) | ((uint32_t)p[2] << 8U) | (uint32_t)p[3]); }};
  343. template<typename I>
  344. class _load_be_bysize<I,8> { public: static ZT_INLINE I l(const uint8_t *const p) noexcept { return (I)(((uint64_t)p[0] << 56U) | ((uint64_t)p[1] << 48U) | ((uint64_t)p[2] << 40U) | ((uint64_t)p[3] << 32U) | ((uint64_t)p[4] << 24U) | ((uint64_t)p[5] << 16U) | ((uint64_t)p[6] << 8U) | (uint64_t)p[7]); }};
  345. template<typename I,unsigned int S>
  346. class _load_le_bysize;
  347. template<typename I>
  348. class _load_le_bysize<I,1> { public: static ZT_INLINE I l(const uint8_t *const p) noexcept { return p[0]; }};
  349. template<typename I>
  350. class _load_le_bysize<I,2> { public: static ZT_INLINE I l(const uint8_t *const p) noexcept { return (I)((unsigned int)p[0] | ((unsigned int)p[1] << 8U)); }};
  351. template<typename I>
  352. class _load_le_bysize<I,4> { public: static ZT_INLINE I l(const uint8_t *const p) noexcept { return (I)((uint32_t)p[0] | ((uint32_t)p[1] << 8U) | ((uint32_t)p[2] << 16U) | ((uint32_t)p[3] << 24U)); }};
  353. template<typename I>
  354. class _load_le_bysize<I,8> { public: static ZT_INLINE I l(const uint8_t *const p) noexcept { return (I)((uint64_t)p[0] | ((uint64_t)p[1] << 8U) | ((uint64_t)p[2] << 16U) | ((uint64_t)p[3] << 24U) | ((uint64_t)p[4] << 32U) | ((uint64_t)p[5] << 40U) | ((uint64_t)p[6] << 48U) | ((uint64_t)p[7]) << 56U); }};
  355. /**
  356. * Convert any signed or unsigned integer type to big-endian ("network") byte order
  357. *
  358. * @tparam I Integer type (usually inferred)
  359. * @param n Value to convert
  360. * @return Value in big-endian order
  361. */
  362. template<typename I>
  363. static ZT_INLINE I hton(const I n) noexcept
  364. {
  365. #if __BYTE_ORDER == __LITTLE_ENDIAN
  366. return _swap_bytes_bysize<I,sizeof(I)>::s(n);
  367. #else
  368. return n;
  369. #endif
  370. }
  371. /**
  372. * Convert any signed or unsigned integer type to host byte order from big-endian ("network") byte order
  373. *
  374. * @tparam I Integer type (usually inferred)
  375. * @param n Value to convert
  376. * @return Value in host byte order
  377. */
  378. template<typename I>
  379. static ZT_INLINE I ntoh(const I n) noexcept
  380. {
  381. #if __BYTE_ORDER == __LITTLE_ENDIAN
  382. return _swap_bytes_bysize<I,sizeof(I)>::s(n);
  383. #else
  384. return n;
  385. #endif
  386. }
  387. /**
  388. * Copy bits from memory into an integer type without modifying their order
  389. *
  390. * @tparam I Type to load
  391. * @param p Byte stream, must be at least sizeof(I) in size
  392. * @return Loaded raw integer
  393. */
  394. template<typename I>
  395. static ZT_INLINE I loadAsIsEndian(const void *const p) noexcept
  396. {
  397. #ifdef ZT_NO_UNALIGNED_ACCESS
  398. I tmp;
  399. for(int i=0;i<(int)sizeof(I);++i)
  400. reinterpret_cast<uint8_t *>(&tmp)[i] = reinterpret_cast<const uint8_t *>(p)[i];
  401. return tmp;
  402. #else
  403. return *reinterpret_cast<const I *>(p);
  404. #endif
  405. }
  406. /**
  407. * Copy bits from memory into an integer type without modifying their order
  408. *
  409. * @tparam I Type to store
  410. * @param p Byte array (must be at least sizeof(I))
  411. * @param i Integer to store
  412. */
  413. template<typename I>
  414. static ZT_INLINE void storeAsIsEndian(void *const p,const I i) noexcept
  415. {
  416. #ifdef ZT_NO_UNALIGNED_ACCESS
  417. for(unsigned int k=0;k<sizeof(I);++k)
  418. reinterpret_cast<uint8_t *>(p)[k] = reinterpret_cast<const uint8_t *>(&i)[k];
  419. #else
  420. *reinterpret_cast<I *>(p) = i;
  421. #endif
  422. }
  423. /**
  424. * Decode a big-endian value from a byte stream
  425. *
  426. * @tparam I Type to decode (should be unsigned e.g. uint32_t or uint64_t)
  427. * @param p Byte stream, must be at least sizeof(I) in size
  428. * @return Decoded integer
  429. */
  430. template<typename I>
  431. static ZT_INLINE I loadBigEndian(const void *const p) noexcept
  432. {
  433. #ifdef ZT_NO_UNALIGNED_ACCESS
  434. return _load_be_bysize<I,sizeof(I)>::l(reinterpret_cast<const uint8_t *>(p));
  435. #else
  436. return ntoh(*reinterpret_cast<const I *>(p));
  437. #endif
  438. }
  439. /**
  440. * Save an integer in big-endian format
  441. *
  442. * @tparam I Integer type to store (usually inferred)
  443. * @param p Byte stream to write (must be at least sizeof(I))
  444. * #param i Integer to write
  445. */
  446. template<typename I>
  447. static ZT_INLINE void storeBigEndian(void *const p,I i) noexcept
  448. {
  449. #ifdef ZT_NO_UNALIGNED_ACCESS
  450. storeAsIsEndian(p,hton(i));
  451. #else
  452. *reinterpret_cast<I *>(p) = hton(i);
  453. #endif
  454. }
  455. /**
  456. * Decode a little-endian value from a byte stream
  457. *
  458. * @tparam I Type to decode
  459. * @param p Byte stream, must be at least sizeof(I) in size
  460. * @return Decoded integer
  461. */
  462. template<typename I>
  463. static ZT_INLINE I loadLittleEndian(const void *const p) noexcept
  464. {
  465. #if __BYTE_ORDER == __BIG_ENDIAN || defined(ZT_NO_UNALIGNED_ACCESS)
  466. return _load_le_bysize<I,sizeof(I)>::l(reinterpret_cast<const uint8_t *>(p));
  467. #else
  468. return *reinterpret_cast<const I *>(p);
  469. #endif
  470. }
  471. /**
  472. * Save an integer in little-endian format
  473. *
  474. * @tparam I Integer type to store (usually inferred)
  475. * @param p Byte stream to write (must be at least sizeof(I))
  476. * #param i Integer to write
  477. */
  478. template<typename I>
  479. static ZT_INLINE void storeLittleEndian(void *const p,const I i) noexcept
  480. {
  481. #if __BYTE_ORDER == __BIG_ENDIAN
  482. storeAsIsEndian(p,_swap_bytes_bysize<I,sizeof(I)>::s(i));
  483. #else
  484. #ifdef ZT_NO_UNALIGNED_ACCESS
  485. storeAsIsEndian(p,i);
  486. #else
  487. *reinterpret_cast<I *>(p) = i;
  488. #endif
  489. #endif
  490. }
  491. } // namespace Utils
  492. } // namespace ZeroTier
  493. #endif