diff --git a/chacha.cpp b/chacha.cpp index 45a706a1..9f27ff66 100644 --- a/chacha.cpp +++ b/chacha.cpp @@ -508,6 +508,12 @@ void XChaCha20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *ke if (rounds != 20) throw InvalidRounds(XChaCha20::StaticAlgorithmName(), rounds); + word64 block; + if (params.GetValue("InitialBlock", block)) + m_state[24] = static_cast(block); + else + m_state[24] = 1; + // Stash key away for use in CipherResynchronize GetBlock get(key); get(m_state[KEY+0])(m_state[KEY+1])(m_state[KEY+2])(m_state[KEY+3]) @@ -539,7 +545,8 @@ void XChaCha20_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *iv m_state[2] = 0x79622d32; m_state[3] = 0x6b206574; // Setup new IV - m_state[12] = 1; m_state[13] = 0; + m_state[12] = m_state[24]; + m_state[13] = 0; m_state[14] = GetWord(false, LITTLE_ENDIAN_ORDER, iv+16); m_state[15] = GetWord(false, LITTLE_ENDIAN_ORDER, iv+20); } diff --git a/chacha.h b/chacha.h index c9d6195a..5e83ff46 100644 --- a/chacha.h +++ b/chacha.h @@ -184,9 +184,9 @@ protected: std::string AlgorithmName() const; std::string AlgorithmProvider() const; - FixedSizeAlignedSecBlock m_state; + FixedSizeAlignedSecBlock m_state; CRYPTOPP_CONSTANT(ROUNDS = XChaCha20_Info::ROUNDS) - CRYPTOPP_CONSTANT(KEY = 16) // Index into m_state + CRYPTOPP_CONSTANT(KEY = 16) // Index into m_state }; /// \brief XChaCha stream cipher