Salsa20.hpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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: 2025-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_SALSA20_HPP
  14. #define ZT_SALSA20_HPP
  15. #include "Constants.hpp"
  16. #include "Utils.hpp"
  17. #include "TriviallyCopyable.hpp"
  18. #ifdef ZT_ARCH_X64
  19. #define ZT_SALSA20_SSE 1
  20. #endif
  21. #define ZT_SALSA20_KEY_SIZE 32
  22. namespace ZeroTier {
  23. /**
  24. * Salsa20 stream cipher
  25. *
  26. * This supports both the 12-round and 20-round variants.
  27. *
  28. * SECURITY: this code only support up to 2^32 bytes per key. This is
  29. * a minor optimization done here because ZeroTier messages are
  30. * nowhere near this large.
  31. */
  32. class Salsa20 : public TriviallyCopyable
  33. {
  34. public:
  35. #ifdef ZT_SALSA20_SSE
  36. static constexpr bool accelerated() noexcept { return true; }
  37. #else
  38. static constexpr bool accelerated() noexcept { return false; }
  39. #endif
  40. ZT_INLINE Salsa20() noexcept {}
  41. ZT_INLINE ~Salsa20() noexcept { Utils::burn(&_state,sizeof(_state)); }
  42. /**
  43. * @param key 256-bit (32 byte) key
  44. * @param iv 64-bit initialization vector
  45. */
  46. ZT_INLINE Salsa20(const void *key,const void *iv) noexcept { init(key,iv); }
  47. /**
  48. * Initialize cipher
  49. *
  50. * @param key Key bits
  51. * @param iv 64-bit initialization vector
  52. */
  53. void init(const void *key,const void *iv) noexcept;
  54. /**
  55. * Encrypt/decrypt data using Salsa20/12
  56. *
  57. * @param in Input data
  58. * @param out Output buffer
  59. * @param bytes Length of data
  60. */
  61. void crypt12(const void *in,void *out,unsigned int bytes) noexcept;
  62. /**
  63. * Encrypt/decrypt data using Salsa20/20
  64. *
  65. * @param in Input data
  66. * @param out Output buffer
  67. * @param bytes Length of data
  68. */
  69. void crypt20(const void *in,void *out,unsigned int bytes) noexcept;
  70. private:
  71. union {
  72. #ifdef ZT_SALSA20_SSE
  73. __m128i v[4];
  74. #endif // ZT_SALSA20_SSE
  75. uint32_t i[16];
  76. } _state;
  77. };
  78. } // namespace ZeroTier
  79. #endif