summaryrefslogtreecommitdiff
path: root/chachapoly.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2019-02-04 06:04:12 -0500
committerJeffrey Walton <noloader@gmail.com>2019-02-04 06:04:12 -0500
commit5b6b86c7f14eb576b4836541c56b7dbdab18c4d7 (patch)
tree2709b845525e0483221a6cfcb95f0c2e7fde0d08 /chachapoly.cpp
parent868ca8e2e5e79c50b9244c3953619353ddd0c444 (diff)
downloadcryptopp-git-5b6b86c7f14eb576b4836541c56b7dbdab18c4d7.tar.gz
Avoid extra call to RekeyCipherAndMac in ChaCha20/Poly1305
Diffstat (limited to 'chachapoly.cpp')
-rw-r--r--chachapoly.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/chachapoly.cpp b/chachapoly.cpp
index bfa4bb89..0da0a785 100644
--- a/chachapoly.cpp
+++ b/chachapoly.cpp
@@ -11,8 +11,8 @@ NAMESPACE_BEGIN(CryptoPP)
// RekeyCipherAndMac is heavier-weight than we like. The Authenc framework was
// predicated on BlockCiphers, where the key and key schedule could be
// calculated independent of the IV being used. However, the ChaCha and
-// ChaCha20Poly1305 construction conflates key setup and IV. That is, both are
-// needed to key or rekey the cipher. Even a simple Resync() forces us to
+// ChaCha20Poly1305 construction combines key setup and IV. That is, both are
+// needed to key or rekey the cipher. Even a simple Resync() requires us to
// regenerate the initial state for both ChaCha20 and Poly1305.
void ChaCha20Poly1305_Base::RekeyCipherAndMac(const byte *userKey, size_t keylength, const NameValuePairs &params)
{
@@ -36,7 +36,16 @@ void ChaCha20Poly1305_Base::SetKeyWithoutResync(const byte *userKey, size_t user
{
CRYPTOPP_ASSERT(userKey && userKeyLength == 32);
m_userKey.Assign(userKey, userKeyLength);
- RekeyCipherAndMac(userKey, userKeyLength, params);
+
+ // ChaCha/Poly1305 initial state depends on both the key and IV. The
+ // IV may or may not be present during the call to SetKeyWithoutResync.
+ // If the IV is present, the framework will call SetKeyWithoutResync
+ // followed by Resynchronize which calls Resync. In this case we defer
+ // calculating the initial state until the call to Resynchronize.
+ // If the IV is not present, it avoids calling ChaCha's SetKey without
+ // an IV, which results in an exception. In this case the user will need
+ // to call Resynchronize to key ChaCha and Poly1305.
+ // RekeyCipherAndMac(userKey, userKeyLength, params);
}
void ChaCha20Poly1305_Base::Resync(const byte *iv, size_t len)
@@ -75,6 +84,7 @@ void ChaCha20Poly1305_Base::AuthenticateLastFooterBlock(byte *mac, size_t macSiz
PutWord(true, LITTLE_ENDIAN_ORDER, length+8, m_totalMessageLength);
AccessMAC().Update(length, sizeof(length));
AccessMAC().TruncatedFinal(mac, macSize);
+ m_state = State_KeySet;
}
void ChaCha20Poly1305_Base::EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *aad, size_t aadLength, const byte *message, size_t messageLength)