aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-03-23 16:47:33 -0400
committerJack Lloyd <[email protected]>2016-03-23 16:47:33 -0400
commit646ddaef38845a7ce33e4dcc7a02500a674c7033 (patch)
tree7d73e0ac634210ea9cb2f03ec983cd60b9e300d0
parentb971daaade75a6923a4c97b9b40b5fdfe2df4992 (diff)
Fix bug in IETF version of ChaCha20Poly1305
If the input lengths are exact multiples of 16 bytes then no padding should be added. Previously 16 bytes of zero padding were added instead.
-rw-r--r--src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp31
-rw-r--r--src/tests/data/aead/chacha20poly1305.vec35
-rw-r--r--src/tests/test_aead.cpp17
3 files changed, 65 insertions, 18 deletions
diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp
index 2350e2e6a..ca4cc15ed 100644
--- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp
+++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp
@@ -1,12 +1,12 @@
/*
* ChaCha20Poly1305 AEAD
-* (C) 2014 Jack Lloyd
+* (C) 2014,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
-#include <botan/internal/mode_utils.h>
#include <botan/chacha20poly1305.h>
+#include <botan/internal/mode_utils.h>
namespace Botan {
@@ -60,18 +60,21 @@ secure_vector<byte> ChaCha20Poly1305_Mode::start_raw(const byte nonce[], size_t
m_chacha->set_iv(nonce, nonce_len);
- secure_vector<byte> zeros(64);
- m_chacha->encrypt(zeros);
+ secure_vector<byte> init(64); // zeros
+ m_chacha->encrypt(init);
- m_poly1305->set_key(zeros.data(), 32);
+ m_poly1305->set_key(init.data(), 32);
// Remainder of output is discard
m_poly1305->update(m_ad);
if(cfrg_version())
{
- std::vector<byte> padding(16 - m_ad.size() % 16);
- m_poly1305->update(padding);
+ if(m_ad.size() % 16)
+ {
+ const byte zeros[16] = { 0 };
+ m_poly1305->update(zeros, 16 - m_ad.size() % 16);
+ }
}
else
{
@@ -97,8 +100,11 @@ void ChaCha20Poly1305_Encryption::finish(secure_vector<byte>& buffer, size_t off
update(buffer, offset);
if(cfrg_version())
{
- std::vector<byte> padding(16 - m_ctext_len % 16);
- m_poly1305->update(padding);
+ if(m_ctext_len % 16)
+ {
+ const byte zeros[16] = { 0 };
+ m_poly1305->update(zeros, 16 - m_ctext_len % 16);
+ }
update_len(m_ad.size());
}
update_len(m_ctext_len);
@@ -138,8 +144,11 @@ void ChaCha20Poly1305_Decryption::finish(secure_vector<byte>& buffer, size_t off
if(cfrg_version())
{
- for(size_t i = 0; i != 16 - m_ctext_len % 16; ++i)
- m_poly1305->update(0);
+ if(m_ctext_len % 16)
+ {
+ const byte zeros[16] = { 0 };
+ m_poly1305->update(zeros, 16 - m_ctext_len % 16);
+ }
update_len(m_ad.size());
}
diff --git a/src/tests/data/aead/chacha20poly1305.vec b/src/tests/data/aead/chacha20poly1305.vec
index e62b29c69..e258bb3af 100644
--- a/src/tests/data/aead/chacha20poly1305.vec
+++ b/src/tests/data/aead/chacha20poly1305.vec
@@ -1,5 +1,6 @@
[ChaCha20Poly1305]
-# draft-agl-tls-chacha20poly1305-04
+
+# From draft-agl-tls-chacha20poly1305-04
Key = 4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007
In = 86d09974840bded2a5ca
@@ -7,7 +8,8 @@ Nonce = cd7cf67be39c794a
AD = 87e229d4500845a079c0
Out = e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6
-# draft-irtf-cfrg-chacha20-poly1305-03
+# From draft-irtf-cfrg-chacha20-poly1305-03
+
In = 4C616469657320616E642047656E746C656D656E206F662074686520636C617373206F66202739393A204966204920636F756C64206F6666657220796F75206F6E6C79206F6E652074697020666F7220746865206675747572652C2073756E73637265656E20776F756C642062652069742E
AD = 50515253C0C1C2C3C4C5C6C7
Key = 808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
@@ -19,3 +21,32 @@ Nonce = 000000000102030405060708
AD = F33388860000000000004E91
In = 496E7465726E65742D4472616674732061726520647261667420646F63756D656E74732076616C696420666F722061206D6178696D756D206F6620736978206D6F6E74687320616E64206D617920626520757064617465642C207265706C616365642C206F72206F62736F6C65746564206279206F7468657220646F63756D656E747320617420616E792074696D652E20497420697320696E617070726F70726961746520746F2075736520496E7465726E65742D447261667473206173207265666572656E6365206D6174657269616C206F7220746F2063697465207468656D206F74686572207468616E206173202FE2809C776F726B20696E2070726F67726573732E2FE2809D
Out = 64A0861575861AF460F062C79BE643BD5E805CFD345CF389F108670AC76C8CB24C6CFC18755D43EEA09EE94E382D26B0BDB7B73C321B0100D4F03B7F355894CF332F830E710B97CE98C8A84ABD0B948114AD176E008D33BD60F982B1FF37C8559797A06EF4F0EF61C186324E2B3506383606907B6A7C02B0F9F6157B53C867E4B9166C767B804D46A59B5216CDE7A4E99040C5A40433225EE282A1B0A06C523EAF4534D7F83FA1155B0047718CBC546A0D072B04B3564EEA1B422273F548271A0BB2316053FA76991955EBD63159434ECEBB4E466DAE5A1073A6727627097A1049E617D91D361094FA68F0FF77987130305BEABA2EDA04DF997B714D6C6F2C29A6AD5CB4022B02709BEEAD9D67890CBB22392336FEA1851F38
+
+# From RFC 7539
+
+Key = 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+Nonce = 070000004041424344454647
+AD = 50515253c0c1c2c3c4c5c6c7
+In = 4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e
+Out = d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691
+
+# Generated by OpenSSL; exposes bug handling plaintexts or AD params
+# with exact multiple of 16 bytes
+
+Key = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+Nonce = BBBBBBBBBBBBBBBBBBBBBBBB
+AD = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+In = DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
+Out = A0C9391216A037370BDFF40626C5DD137E93A01836AF9B8A5C1F929EF18C9350
+
+Key = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+Nonce = BBBBBBBBBBBBBBBBBBBBBBBB
+AD = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+In = DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
+Out = A0C9391216A037370BDFF40626C5DD13422D6D1564BCE2074D98279498CE4C86
+
+Key = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+Nonce = BBBBBBBBBBBBBBBBBBBBBBBB
+AD = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+In = DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+Out = A0C9391216A037370BDFF40626C5DD13D45447FBEBA3C985BF65FBCBE51663F9214F9C6757F9FC0CFF3135E68DC7251F
diff --git a/src/tests/test_aead.cpp b/src/tests/test_aead.cpp
index a31996fad..e7756d5bb 100644
--- a/src/tests/test_aead.cpp
+++ b/src/tests/test_aead.cpp
@@ -1,5 +1,5 @@
/*
-* (C) 2014,2015 Jack Lloyd
+* (C) 2014,2015,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -54,10 +54,17 @@ class AEAD_Tests : public Text_Based_Test
buf.assign(expected.begin(), expected.end());
- dec->set_key(key);
- dec->set_associated_data_vec(ad);
- dec->start(nonce);
- dec->finish(buf);
+ try
+ {
+ dec->set_key(key);
+ dec->set_associated_data_vec(ad);
+ dec->start(nonce);
+ dec->finish(buf);
+ }
+ catch(Botan::Exception& e)
+ {
+ result.test_failure("Failure processing AEAD ciphertext");
+ }
if(enc->authenticated())
{