Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:54

0001 // chacha.h - written and placed in the public domain by Jeffrey Walton.

0002 //            Based on Wei Dai's Salsa20, Botan's SSE2 implementation,

0003 //            and Bernstein's reference ChaCha family implementation at

0004 //            http://cr.yp.to/chacha.html.

0005 
0006 // The library added Bernstein's ChaCha classes at Crypto++ 5.6.4. The IETF

0007 // uses a slightly different implementation than Bernstein, and the IETF

0008 // ChaCha and XChaCha classes were added at Crypto++ 8.1. We wanted to maintain

0009 // ABI compatibility at the 8.1 release so the original ChaCha classes were not

0010 // disturbed. Instead new classes were added for IETF ChaCha. The back-end

0011 // implementation shares code as expected, however.

0012 
0013 /// \file chacha.h

0014 /// \brief Classes for ChaCha8, ChaCha12 and ChaCha20 stream ciphers

0015 /// \details Crypto++ provides Bernstein and ECRYPT's ChaCha from <a

0016 ///  href="http://cr.yp.to/chacha/chacha-20080128.pdf">ChaCha, a

0017 ///  variant of Salsa20</a> (2008.01.28). Crypto++ also provides the

0018 ///  IETF implementation of ChaCha using the ChaChaTLS name. Bernstein's

0019 ///  implementation is _slightly_ different from the TLS working group's

0020 ///  implementation for cipher suites

0021 ///  <tt>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>,

0022 ///  <tt>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</tt>,

0023 ///  and <tt>TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>. Finally,

0024 ///  the library provides <a

0025 ///  href="https://tools.ietf.org/html/draft-arciszewski-xchacha">XChaCha:

0026 ///  eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305 (rev. 03)</a>.

0027 /// \since ChaCha since Crypto++ 5.6.4, ChaChaTLS and XChaCha20 since Crypto++ 8.1

0028 
0029 #ifndef CRYPTOPP_CHACHA_H
0030 #define CRYPTOPP_CHACHA_H
0031 
0032 #include "strciphr.h"
0033 #include "secblock.h"
0034 
0035 NAMESPACE_BEGIN(CryptoPP)
0036 
0037 ////////////////////////////// Bernstein ChaCha //////////////////////////////

0038 
0039 /// \brief ChaCha stream cipher information

0040 /// \since Crypto++ 5.6.4

0041 struct ChaCha_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8>
0042 {
0043     /// \brief The algorithm name

0044     /// \return the algorithm name

0045     /// \details StaticAlgorithmName returns the algorithm's name as a static

0046     ///  member function.

0047     /// \details Bernstein named the cipher variants ChaCha8, ChaCha12 and

0048     ///  ChaCha20. More generally, Bernstein called the family ChaCha{r}.

0049     ///  AlgorithmName() provides the exact name once rounds are set.

0050     static const char* StaticAlgorithmName() {
0051         return "ChaCha";
0052     }
0053 };
0054 
0055 /// \brief ChaCha stream cipher implementation

0056 /// \since Crypto++ 5.6.4

0057 class CRYPTOPP_NO_VTABLE ChaCha_Policy : public AdditiveCipherConcretePolicy<word32, 16>
0058 {
0059 public:
0060     virtual ~ChaCha_Policy() {}
0061     ChaCha_Policy() : m_rounds(ROUNDS) {}
0062 
0063 protected:
0064     void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
0065     void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
0066     void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
0067     bool CipherIsRandomAccess() const {return true;}
0068     void SeekToIteration(lword iterationCount);
0069     unsigned int GetAlignment() const;
0070     unsigned int GetOptimalBlockSize() const;
0071 
0072     std::string AlgorithmName() const;
0073     std::string AlgorithmProvider() const;
0074 
0075     CRYPTOPP_CONSTANT(ROUNDS = 20);  // Default rounds

0076     FixedSizeAlignedSecBlock<word32, 16> m_state;
0077     unsigned int m_rounds;
0078 };
0079 
0080 /// \brief ChaCha stream cipher

0081 /// \details This is Bernstein and ECRYPT's ChaCha. It is _slightly_ different

0082 ///  from the IETF's version of ChaCha called ChaChaTLS.

0083 /// \sa <a href="http://cr.yp.to/chacha/chacha-20080208.pdf">ChaCha, a variant

0084 ///  of Salsa20</a> (2008.01.28).

0085 /// \since Crypto++ 5.6.4

0086 struct ChaCha : public ChaCha_Info, public SymmetricCipherDocumentation
0087 {
0088     /// \brief ChaCha Encryption

0089     typedef SymmetricCipherFinal<ConcretePolicyHolder<ChaCha_Policy, AdditiveCipherTemplate<> >, ChaCha_Info > Encryption;
0090     /// \brief ChaCha Decryption

0091     typedef Encryption Decryption;
0092 };
0093 
0094 ////////////////////////////// IETF ChaChaTLS //////////////////////////////

0095 
0096 /// \brief IETF ChaCha20 stream cipher information

0097 /// \since Crypto++ 8.1

0098 struct ChaChaTLS_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 12>, FixedRounds<20>
0099 {
0100     /// \brief The algorithm name

0101     /// \return the algorithm name

0102     /// \details StaticAlgorithmName returns the algorithm's name as a static

0103     ///  member function.

0104     /// \details This is the IETF's variant of Bernstein's ChaCha from RFC

0105     ///  8439. IETF ChaCha is called ChaChaTLS in the Crypto++ library. It

0106     ///  is _slightly_ different from Bernstein's implementation.

0107     static const char* StaticAlgorithmName() {
0108         return "ChaChaTLS";
0109     }
0110 };
0111 
0112 /// \brief IETF ChaCha20 stream cipher implementation

0113 /// \since Crypto++ 8.1

0114 class CRYPTOPP_NO_VTABLE ChaChaTLS_Policy : public AdditiveCipherConcretePolicy<word32, 16>
0115 {
0116 public:
0117     virtual ~ChaChaTLS_Policy() {}
0118     ChaChaTLS_Policy() : m_counter(0) {}
0119 
0120 protected:
0121     void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
0122     void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
0123     void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
0124     bool CipherIsRandomAccess() const {return true;}
0125     void SeekToIteration(lword iterationCount);
0126     unsigned int GetAlignment() const;
0127     unsigned int GetOptimalBlockSize() const;
0128 
0129     std::string AlgorithmName() const;
0130     std::string AlgorithmProvider() const;
0131 
0132     FixedSizeAlignedSecBlock<word32, 16+8> m_state;
0133     unsigned int m_counter;
0134     CRYPTOPP_CONSTANT(ROUNDS = ChaChaTLS_Info::ROUNDS);
0135     CRYPTOPP_CONSTANT(KEY = 16);  // Index into m_state

0136     CRYPTOPP_CONSTANT(CTR = 24);  // Index into m_state

0137 };
0138 
0139 /// \brief IETF ChaCha20 stream cipher

0140 /// \details This is the IETF's variant of Bernstein's ChaCha from RFC 8439.

0141 ///  IETF ChaCha is called ChaChaTLS in the Crypto++ library. It is

0142 ///  _slightly_ different from the Bernstein implementation. ChaCha-TLS

0143 ///  can be used for cipher suites

0144 ///  <tt>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>,

0145 ///  <tt>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256</tt>, and

0146 ///  <tt>TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256</tt>.

0147 /// \sa <a href="https://tools.ietf.org/html/rfc8439">RFC 8439, ChaCha20 and

0148 ///  Poly1305 for IETF Protocols</a>, <A

0149 ///  HREF="https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU">How

0150 ///  to handle block counter wrap in IETF's ChaCha algorithm?</A> and

0151 ///  <A HREF="https://github.com/weidai11/cryptopp/issues/790">Issue

0152 ///  790, ChaChaTLS results when counter block wraps</A>.

0153 /// \since Crypto++ 8.1

0154 struct ChaChaTLS : public ChaChaTLS_Info, public SymmetricCipherDocumentation
0155 {
0156     /// \brief ChaCha-TLS Encryption

0157     typedef SymmetricCipherFinal<ConcretePolicyHolder<ChaChaTLS_Policy, AdditiveCipherTemplate<> >, ChaChaTLS_Info > Encryption;
0158     /// \brief ChaCha-TLS Decryption

0159     typedef Encryption Decryption;
0160 };
0161 
0162 ////////////////////////////// IETF XChaCha20 draft //////////////////////////////

0163 
0164 /// \brief IETF XChaCha20 stream cipher information

0165 /// \since Crypto++ 8.1

0166 struct XChaCha20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24>
0167 {
0168     /// \brief The algorithm name

0169     /// \return the algorithm name

0170     /// \details StaticAlgorithmName returns the algorithm's name as a static

0171     ///  member function.

0172     /// \details This is the IETF's XChaCha from draft-arciszewski-xchacha.

0173     static const char* StaticAlgorithmName() {
0174         return "XChaCha20";
0175     }
0176 };
0177 
0178 /// \brief IETF XChaCha20 stream cipher implementation

0179 /// \since Crypto++ 8.1

0180 class CRYPTOPP_NO_VTABLE XChaCha20_Policy : public AdditiveCipherConcretePolicy<word32, 16>
0181 {
0182 public:
0183     virtual ~XChaCha20_Policy() {}
0184     XChaCha20_Policy() : m_counter(0), m_rounds(ROUNDS) {}
0185 
0186 protected:
0187     void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
0188     void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
0189     void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
0190     bool CipherIsRandomAccess() const {return false;}
0191     void SeekToIteration(lword iterationCount);
0192     unsigned int GetAlignment() const;
0193     unsigned int GetOptimalBlockSize() const;
0194 
0195     std::string AlgorithmName() const;
0196     std::string AlgorithmProvider() const;
0197 
0198     FixedSizeAlignedSecBlock<word32, 16+8> m_state;
0199     unsigned int m_counter, m_rounds;
0200     CRYPTOPP_CONSTANT(ROUNDS = 20);  // Default rounds

0201     CRYPTOPP_CONSTANT(KEY = 16);  // Index into m_state

0202 };
0203 
0204 /// \brief IETF XChaCha20 stream cipher

0205 /// \details This is the IETF's XChaCha from draft-arciszewski-xchacha.

0206 /// \sa <a href="https://tools.ietf.org/html/draft-arciszewski-xchacha">XChaCha:

0207 ///  eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305 (rev. 03)</a>, <A

0208 ///  HREF="https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU">How

0209 ///  to handle block counter wrap in IETF's ChaCha algorithm?</A> and

0210 ///  <A HREF="https://github.com/weidai11/cryptopp/issues/790">Issue

0211 ///  790, ChaCha20 results when counter block wraps</A>.

0212 /// \since Crypto++ 8.1

0213 struct XChaCha20 : public XChaCha20_Info, public SymmetricCipherDocumentation
0214 {
0215     /// \brief XChaCha Encryption

0216     typedef SymmetricCipherFinal<ConcretePolicyHolder<XChaCha20_Policy, AdditiveCipherTemplate<> >, XChaCha20_Info > Encryption;
0217     /// \brief XChaCha Decryption

0218     typedef Encryption Decryption;
0219 };
0220 
0221 NAMESPACE_END
0222 
0223 #endif  // CRYPTOPP_CHACHA_H