aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp37
-rw-r--r--src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h7
-rw-r--r--src/tests/data/aead/chacha20poly1305.vec8
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<byte> 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<byte> 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<byte>();
}
@@ -80,9 +94,12 @@ void ChaCha20Poly1305_Encryption::update(secure_vector<byte>& buffer, size_t off
void ChaCha20Poly1305_Encryption::finish(secure_vector<byte>& 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<byte> mac = m_poly1305->final();
@@ -118,9 +135,13 @@ void ChaCha20Poly1305_Decryption::finish(secure_vector<byte>& 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<byte> 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<MessageAuthenticationCode> m_poly1305;
secure_vector<byte> 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<byte> 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