From 76bdb328a68119db409e5ce5d8c85f398a333fee Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Fri, 25 Jan 2019 21:51:43 -0500 Subject: [PATCH] Switch to RFC 8439 for ChaChaTLS Unfortunately the block counter wrap problem is still present. --- chacha.cpp | 16 +++++++++++----- chacha.h | 10 ++++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/chacha.cpp b/chacha.cpp index 0311a56d..9d0f357e 100644 --- a/chacha.cpp +++ b/chacha.cpp @@ -388,8 +388,8 @@ void ChaChaTLS_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *ke if (rounds != 20) throw InvalidRounds(ChaChaTLS::StaticAlgorithmName(), rounds); - // RFC 7539 test vectors use an initial block counter. However, the counter - // can be an arbitrary value per RFC 7539 Section 2.4. We stash the counter + // RFC 8439 test vectors use an initial block counter. However, the counter + // can be an arbitrary value per RFC 8439 Section 2.4. We stash the counter // away in state[16] and use it for a Resynchronize() operation. I think // the initial counter is used more like a Tweak when non-0, and it should // be provided in Resynchronize() (light-weight re-keying). However, @@ -401,13 +401,13 @@ void ChaChaTLS_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *ke else m_state[16] = 0; - // State words are defined in RFC 7539, Section 2.3. + // State words are defined in RFC 8439, Section 2.3. m_state[0] = 0x61707865; m_state[1] = 0x3320646e; m_state[2] = 0x79622d32; m_state[3] = 0x6b206574; - // State words are defined in RFC 7539, Section 2.3. Key is 32-bytes. + // State words are defined in RFC 8439, Section 2.3. Key is 32-bytes. GetBlock get(key); get(m_state[4])(m_state[5])(m_state[6])(m_state[7])(m_state[8])(m_state[9])(m_state[10])(m_state[11]); } @@ -417,12 +417,18 @@ void ChaChaTLS_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length); CRYPTOPP_ASSERT(length==12); - // State words are defined in RFC 7539, Section 2.3 + // State words are defined in RFC 8439, Section 2.3 GetBlock get(IV); m_state[12] = m_state[16]; get(m_state[13])(m_state[14])(m_state[15]); } +void ChaChaTLS_Policy::CipherResynchronize(byte *keystreamBuffer, word32 initialBlock, const byte *IV, size_t length) +{ + m_state[16] = initialBlock; + this->CipherResynchronize(keystreamBuffer, IV, length); +} + void ChaChaTLS_Policy::SeekToIteration(lword iterationCount) { // Should we throw here??? If the initial block counter is diff --git a/chacha.h b/chacha.h index 28b195f6..9be96253 100644 --- a/chacha.h +++ b/chacha.h @@ -95,7 +95,7 @@ struct ChaChaTLS_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_ /// \details StaticAlgorithmName returns the algorithm's name as a static /// member function. /// \details This is the IETF's variant of Bernstein's ChaCha from RFC - /// 7539. IETF ChaCha is called ChaChaTLS in the Crypto++ library. It + /// 8439. IETF ChaCha is called ChaChaTLS in the Crypto++ library. It /// is _slightly_ different from Bernstein's implementation. static const char* StaticAlgorithmName() { return "ChaChaTLS"; @@ -114,6 +114,7 @@ protected: void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length); + void CipherResynchronize(byte *keystreamBuffer, word32 initialBlock, const byte *IV, size_t length); bool CipherIsRandomAccess() const {return true;} void SeekToIteration(lword iterationCount); unsigned int GetAlignment() const; @@ -127,15 +128,16 @@ protected: }; /// \brief ChaCha-TLS stream cipher -/// \details This is the IETF's variant of Bernstein's ChaCha from RFC 7539. +/// \details This is the IETF's variant of Bernstein's ChaCha from RFC 8439. /// IETF ChaCha is called ChaChaTLS in the Crypto++ library. It is /// _slightly_ different from the Bernstein implementation. ChaCha-TLS /// can be used for cipher suites /// TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, /// TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, and /// TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256. -/// \sa ChaCha20 and Poly1305 for -/// IETF Protocols. +/// \sa ChaCha20 and Poly1305 for +/// IETF Protocols and Issue +/// 790, ChaChaTLS results when counter block wraps. /// \since Crypto++ 8.1 struct ChaChaTLS : public ChaChaTLS_Info, public SymmetricCipherDocumentation {