From 9a59362b3b754abf1d06c14cfa7decf9ef16bd6e Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 31 Dec 2014 14:21:57 +0000 Subject: Support the older ChaCha20Poly1305 AEAD from draft-agl-tls-chacha20poly1305-04 which we distinguish by the nonce size (always 64 bits in this format, always 96 bits in the CFRG document). --- .../aead/chacha20poly1305/chacha20poly1305.cpp | 37 +++++++++++++++++----- .../modes/aead/chacha20poly1305/chacha20poly1305.h | 7 ++-- src/tests/data/aead/chacha20poly1305.vec | 8 +++++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp index 6f835ca6b..db215b66b 100644 --- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp +++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp @@ -13,6 +13,11 @@ namespace Botan { +bool ChaCha20Poly1305_Mode::valid_nonce_length(size_t n) const + { + return (n == 8 || n == 12); + } + void ChaCha20Poly1305_Mode::clear() { m_chacha.reset(); @@ -48,6 +53,7 @@ secure_vector ChaCha20Poly1305_Mode::start_raw(const byte nonce[], size_t throw Invalid_IV_Length(name(), nonce_len); m_ctext_len = 0; + m_nonce_len = nonce_len; m_chacha->set_iv(nonce, nonce_len); @@ -60,8 +66,16 @@ secure_vector ChaCha20Poly1305_Mode::start_raw(const byte nonce[], size_t // Remainder of output is discard m_poly1305->update(m_ad); - for(size_t i = 0; i != 16 - m_ad.size() % 16; ++i) - m_poly1305->update(0); + + if(cfrg_version()) + { + for(size_t i = 0; i != 16 - m_ad.size() % 16; ++i) + m_poly1305->update(0); + } + else + { + update_len(m_ad.size()); + } return secure_vector(); } @@ -80,9 +94,12 @@ void ChaCha20Poly1305_Encryption::update(secure_vector& buffer, size_t off void ChaCha20Poly1305_Encryption::finish(secure_vector& buffer, size_t offset) { update(buffer, offset); - for(size_t i = 0; i != 16 - m_ctext_len % 16; ++i) - m_poly1305->update(0); - update_len(m_ad.size()); + if(cfrg_version()) + { + for(size_t i = 0; i != 16 - m_ctext_len % 16; ++i) + m_poly1305->update(0); + update_len(m_ad.size()); + } update_len(m_ctext_len); const secure_vector mac = m_poly1305->final(); @@ -118,9 +135,13 @@ void ChaCha20Poly1305_Decryption::finish(secure_vector& buffer, size_t off m_ctext_len += remaining; } - for(size_t i = 0; i != 16 - m_ctext_len % 16; ++i) - m_poly1305->update(0); - update_len(m_ad.size()); + if(cfrg_version()) + { + for(size_t i = 0; i != 16 - m_ctext_len % 16; ++i) + m_poly1305->update(0); + update_len(m_ad.size()); + } + update_len(m_ctext_len); const secure_vector mac = m_poly1305->final(); diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h index de4560be7..fbeecba05 100644 --- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h +++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h @@ -17,6 +17,8 @@ namespace Botan { /** * Base class * See draft-irtf-cfrg-chacha20-poly1305-03 for specification +* If a nonce of 64 bits is used the older version described in +* draft-agl-tls-chacha20poly1305-04 is used instead. */ class BOTAN_DLL ChaCha20Poly1305_Mode : public AEAD_Mode { @@ -30,8 +32,7 @@ class BOTAN_DLL ChaCha20Poly1305_Mode : public AEAD_Mode Key_Length_Specification key_spec() const override { return Key_Length_Specification(32); } - bool valid_nonce_length(size_t n) const override - { return (n == 12); } + bool valid_nonce_length(size_t n) const override; size_t tag_size() const override { return 16; } @@ -41,8 +42,10 @@ class BOTAN_DLL ChaCha20Poly1305_Mode : public AEAD_Mode std::unique_ptr m_poly1305; secure_vector m_ad; + size_t m_nonce_len = 0; size_t m_ctext_len = 0; + bool cfrg_version() const { return m_nonce_len == 12; } void update_len(size_t len); private: secure_vector start_raw(const byte nonce[], size_t nonce_len) override; diff --git a/src/tests/data/aead/chacha20poly1305.vec b/src/tests/data/aead/chacha20poly1305.vec index 5b5f8397d..e62b29c69 100644 --- a/src/tests/data/aead/chacha20poly1305.vec +++ b/src/tests/data/aead/chacha20poly1305.vec @@ -1,4 +1,12 @@ [ChaCha20Poly1305] +# draft-agl-tls-chacha20poly1305-04 + +Key = 4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007 +In = 86d09974840bded2a5ca +Nonce = cd7cf67be39c794a +AD = 87e229d4500845a079c0 +Out = e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6 + # draft-irtf-cfrg-chacha20-poly1305-03 In = 4C616469657320616E642047656E746C656D656E206F662074686520636C617373206F66202739393A204966204920636F756C64206F6666657220796F75206F6E6C79206F6E652074697020666F7220746865206675747572652C2073756E73637265656E20776F756C642062652069742E AD = 50515253C0C1C2C3C4C5C6C7 -- cgit v1.2.3