chacha.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // chacha.h - written and placed in the public domain by Jeffrey Walton.
  2. // Based on Wei Dai's Salsa20, Botan's SSE2 implementation,
  3. // and Bernstein's reference ChaCha family implementation at
  4. // http://cr.yp.to/chacha.html.
  5. // The library added Bernstein's ChaCha classes at Crypto++ 5.6.4. The IETF
  6. // uses a slightly different implementation than Bernstein, and the IETF
  7. // ChaCha and XChaCha classes were added at Crypto++ 8.1. We wanted to maintain
  8. // ABI compatibility at the 8.1 release so the original ChaCha classes were not
  9. // disturbed. Instead new classes were added for IETF ChaCha. The back-end
  10. // implementation shares code as expected, however.
  11. /// \file chacha.h
  12. /// \brief Classes for ChaCha8, ChaCha12 and ChaCha20 stream ciphers
  13. /// \details Crypto++ provides Bernstein and ECRYPT's ChaCha from <a
  14. /// href="http://cr.yp.to/chacha/chacha-20080128.pdf">ChaCha, a
  15. /// variant of Salsa20</a> (2008.01.28). Crypto++ also provides the
  16. /// IETF implementation of ChaCha using the ChaChaTLS name. Bernstein's
  17. /// implementation is _slightly_ different from the TLS working group's
  18. /// implementation for cipher suites
  19. /// <tt>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>,
  20. /// <tt>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</tt>,
  21. /// and <tt>TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>. Finally,
  22. /// the library provides <a
  23. /// href="https://tools.ietf.org/html/draft-arciszewski-xchacha">XChaCha:
  24. /// eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305 (rev. 03)</a>.
  25. /// \since ChaCha since Crypto++ 5.6.4, ChaChaTLS and XChaCha20 since Crypto++ 8.1
  26. #ifndef CRYPTOPP_CHACHA_H
  27. #define CRYPTOPP_CHACHA_H
  28. #include "strciphr.h"
  29. #include "secblock.h"
  30. NAMESPACE_BEGIN(CryptoPP)
  31. ////////////////////////////// Bernstein ChaCha //////////////////////////////
  32. /// \brief ChaCha stream cipher information
  33. /// \since Crypto++ 5.6.4
  34. struct ChaCha_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8>
  35. {
  36. /// \brief The algorithm name
  37. /// \return the algorithm name
  38. /// \details StaticAlgorithmName returns the algorithm's name as a static
  39. /// member function.
  40. /// \details Bernstein named the cipher variants ChaCha8, ChaCha12 and
  41. /// ChaCha20. More generally, Bernstein called the family ChaCha{r}.
  42. /// AlgorithmName() provides the exact name once rounds are set.
  43. static const char* StaticAlgorithmName() {
  44. return "ChaCha";
  45. }
  46. };
  47. /// \brief ChaCha stream cipher implementation
  48. /// \since Crypto++ 5.6.4
  49. class CRYPTOPP_NO_VTABLE ChaCha_Policy : public AdditiveCipherConcretePolicy<word32, 16>
  50. {
  51. public:
  52. virtual ~ChaCha_Policy() {}
  53. ChaCha_Policy() : m_rounds(ROUNDS) {}
  54. protected:
  55. void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
  56. void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
  57. void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
  58. bool CipherIsRandomAccess() const {return true;}
  59. void SeekToIteration(lword iterationCount);
  60. unsigned int GetAlignment() const;
  61. unsigned int GetOptimalBlockSize() const;
  62. std::string AlgorithmName() const;
  63. std::string AlgorithmProvider() const;
  64. CRYPTOPP_CONSTANT(ROUNDS = 20); // Default rounds
  65. FixedSizeAlignedSecBlock<word32, 16> m_state;
  66. unsigned int m_rounds;
  67. };
  68. /// \brief ChaCha stream cipher
  69. /// \details This is Bernstein and ECRYPT's ChaCha. It is _slightly_ different
  70. /// from the IETF's version of ChaCha called ChaChaTLS.
  71. /// \sa <a href="http://cr.yp.to/chacha/chacha-20080208.pdf">ChaCha, a variant
  72. /// of Salsa20</a> (2008.01.28).
  73. /// \since Crypto++ 5.6.4
  74. struct ChaCha : public ChaCha_Info, public SymmetricCipherDocumentation
  75. {
  76. /// \brief ChaCha Encryption
  77. typedef SymmetricCipherFinal<ConcretePolicyHolder<ChaCha_Policy, AdditiveCipherTemplate<> >, ChaCha_Info > Encryption;
  78. /// \brief ChaCha Decryption
  79. typedef Encryption Decryption;
  80. };
  81. ////////////////////////////// IETF ChaChaTLS //////////////////////////////
  82. /// \brief IETF ChaCha20 stream cipher information
  83. /// \since Crypto++ 8.1
  84. struct ChaChaTLS_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 12>, FixedRounds<20>
  85. {
  86. /// \brief The algorithm name
  87. /// \return the algorithm name
  88. /// \details StaticAlgorithmName returns the algorithm's name as a static
  89. /// member function.
  90. /// \details This is the IETF's variant of Bernstein's ChaCha from RFC
  91. /// 8439. IETF ChaCha is called ChaChaTLS in the Crypto++ library. It
  92. /// is _slightly_ different from Bernstein's implementation.
  93. static const char* StaticAlgorithmName() {
  94. return "ChaChaTLS";
  95. }
  96. };
  97. /// \brief IETF ChaCha20 stream cipher implementation
  98. /// \since Crypto++ 8.1
  99. class CRYPTOPP_NO_VTABLE ChaChaTLS_Policy : public AdditiveCipherConcretePolicy<word32, 16>
  100. {
  101. public:
  102. virtual ~ChaChaTLS_Policy() {}
  103. ChaChaTLS_Policy() : m_counter(0) {}
  104. protected:
  105. void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
  106. void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
  107. void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
  108. bool CipherIsRandomAccess() const {return true;}
  109. void SeekToIteration(lword iterationCount);
  110. unsigned int GetAlignment() const;
  111. unsigned int GetOptimalBlockSize() const;
  112. std::string AlgorithmName() const;
  113. std::string AlgorithmProvider() const;
  114. FixedSizeAlignedSecBlock<word32, 16+8> m_state;
  115. unsigned int m_counter;
  116. CRYPTOPP_CONSTANT(ROUNDS = ChaChaTLS_Info::ROUNDS);
  117. CRYPTOPP_CONSTANT(KEY = 16); // Index into m_state
  118. CRYPTOPP_CONSTANT(CTR = 24); // Index into m_state
  119. };
  120. /// \brief IETF ChaCha20 stream cipher
  121. /// \details This is the IETF's variant of Bernstein's ChaCha from RFC 8439.
  122. /// IETF ChaCha is called ChaChaTLS in the Crypto++ library. It is
  123. /// _slightly_ different from the Bernstein implementation. ChaCha-TLS
  124. /// can be used for cipher suites
  125. /// <tt>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>,
  126. /// <tt>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</tt>, and
  127. /// <tt>TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>.
  128. /// \sa <a href="https://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and
  129. /// Poly1305 for IETF Protocols</a>, <A
  130. /// HREF="https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU">How
  131. /// to handle block counter wrap in IETF's ChaCha algorithm?</A> and
  132. /// <A HREF="https://github.com/weidai11/cryptopp/issues/790">Issue
  133. /// 790, ChaChaTLS results when counter block wraps</A>.
  134. /// \since Crypto++ 8.1
  135. struct ChaChaTLS : public ChaChaTLS_Info, public SymmetricCipherDocumentation
  136. {
  137. /// \brief ChaCha-TLS Encryption
  138. typedef SymmetricCipherFinal<ConcretePolicyHolder<ChaChaTLS_Policy, AdditiveCipherTemplate<> >, ChaChaTLS_Info > Encryption;
  139. /// \brief ChaCha-TLS Decryption
  140. typedef Encryption Decryption;
  141. };
  142. ////////////////////////////// IETF XChaCha20 draft //////////////////////////////
  143. /// \brief IETF XChaCha20 stream cipher information
  144. /// \since Crypto++ 8.1
  145. struct XChaCha20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24>
  146. {
  147. /// \brief The algorithm name
  148. /// \return the algorithm name
  149. /// \details StaticAlgorithmName returns the algorithm's name as a static
  150. /// member function.
  151. /// \details This is the IETF's XChaCha from draft-arciszewski-xchacha.
  152. static const char* StaticAlgorithmName() {
  153. return "XChaCha20";
  154. }
  155. };
  156. /// \brief IETF XChaCha20 stream cipher implementation
  157. /// \since Crypto++ 8.1
  158. class CRYPTOPP_NO_VTABLE XChaCha20_Policy : public AdditiveCipherConcretePolicy<word32, 16>
  159. {
  160. public:
  161. virtual ~XChaCha20_Policy() {}
  162. XChaCha20_Policy() : m_counter(0), m_rounds(ROUNDS) {}
  163. protected:
  164. void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
  165. void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
  166. void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
  167. bool CipherIsRandomAccess() const {return false;}
  168. void SeekToIteration(lword iterationCount);
  169. unsigned int GetAlignment() const;
  170. unsigned int GetOptimalBlockSize() const;
  171. std::string AlgorithmName() const;
  172. std::string AlgorithmProvider() const;
  173. FixedSizeAlignedSecBlock<word32, 16+8> m_state;
  174. unsigned int m_counter, m_rounds;
  175. CRYPTOPP_CONSTANT(ROUNDS = 20); // Default rounds
  176. CRYPTOPP_CONSTANT(KEY = 16); // Index into m_state
  177. };
  178. /// \brief IETF XChaCha20 stream cipher
  179. /// \details This is the IETF's XChaCha from draft-arciszewski-xchacha.
  180. /// \sa <a href="https://tools.ietf.org/html/draft-arciszewski-xchacha">XChaCha:
  181. /// eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305 (rev. 03)</a>, <A
  182. /// HREF="https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU">How
  183. /// to handle block counter wrap in IETF's ChaCha algorithm?</A> and
  184. /// <A HREF="https://github.com/weidai11/cryptopp/issues/790">Issue
  185. /// 790, ChaCha20 results when counter block wraps</A>.
  186. /// \since Crypto++ 8.1
  187. struct XChaCha20 : public XChaCha20_Info, public SymmetricCipherDocumentation
  188. {
  189. /// \brief XChaCha Encryption
  190. typedef SymmetricCipherFinal<ConcretePolicyHolder<XChaCha20_Policy, AdditiveCipherTemplate<> >, XChaCha20_Info > Encryption;
  191. /// \brief XChaCha Decryption
  192. typedef Encryption Decryption;
  193. };
  194. NAMESPACE_END
  195. #endif // CRYPTOPP_CHACHA_H