aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-02-02 22:43:38 -0500
committerJack Lloyd <[email protected]>2017-02-02 22:43:38 -0500
commit23a96ca126ebfddb2259386f12a00a8e783226ed (patch)
tree03b8bb5224a2ae7de2c0a94e54bd28631717ddf8
parentae8d2bd859120839ee08bc35daebda7ef4971ea6 (diff)
Support zero-length IV in ChaCha
Equivalent to an 8 byte all-zero IV, same handling as Salsa.
-rw-r--r--src/lib/stream/chacha/chacha.cpp13
-rw-r--r--src/lib/stream/chacha/chacha.h7
-rw-r--r--src/tests/data/stream/chacha.vec3
3 files changed, 20 insertions, 3 deletions
diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp
index 4befe1981..d56f9e60a 100644
--- a/src/lib/stream/chacha/chacha.cpp
+++ b/src/lib/stream/chacha/chacha.cpp
@@ -171,6 +171,11 @@ void ChaCha::key_schedule(const uint8_t key[], size_t length)
set_iv(ZERO, sizeof(ZERO));
}
+bool ChaCha::valid_iv_length(size_t iv_len) const
+ {
+ return (iv_len == 0 || iv_len == 8 || iv_len == 12);
+ }
+
void ChaCha::set_iv(const uint8_t iv[], size_t length)
{
if(!valid_iv_length(length))
@@ -179,7 +184,13 @@ void ChaCha::set_iv(const uint8_t iv[], size_t length)
m_state[12] = 0;
m_state[13] = 0;
- if(length == 8)
+ if(length == 0)
+ {
+ // Treat zero length IV same as an all-zero IV
+ m_state[14] = 0;
+ m_state[15] = 0;
+ }
+ else if(length == 8)
{
m_state[14] = load_le<uint32_t>(iv, 0);
m_state[15] = load_le<uint32_t>(iv, 1);
diff --git a/src/lib/stream/chacha/chacha.h b/src/lib/stream/chacha/chacha.h
index 876b9ca33..64a387ec5 100644
--- a/src/lib/stream/chacha/chacha.h
+++ b/src/lib/stream/chacha/chacha.h
@@ -33,8 +33,11 @@ class BOTAN_DLL ChaCha final : public StreamCipher
void set_iv(const uint8_t iv[], size_t iv_len) override;
- bool valid_iv_length(size_t iv_len) const override
- { return (iv_len == 8 || iv_len == 12); }
+ /*
+ * ChaCha accepts 0, 8, or 12 byte IVs. The default IV is a 8 zero bytes.
+ * An IV of length 0 is treated the same as the default zero IV.
+ */
+ bool valid_iv_length(size_t iv_len) const override;
Key_Length_Specification key_spec() const override
{
diff --git a/src/tests/data/stream/chacha.vec b/src/tests/data/stream/chacha.vec
index f7ba701ba..a361a913a 100644
--- a/src/tests/data/stream/chacha.vec
+++ b/src/tests/data/stream/chacha.vec
@@ -6,6 +6,9 @@
# Tests got from the original implementation of Daniel J. Bernstein
Key = 00000000000000000000000000000000
+Out = E28A5FA4A67F8C5DEFED3E6FB7303486AA8427D31419A729572D777953491120B64AB8E72B8DEB85CD6AEA7CB6089A101824BEEB08814A428AAB1FA2C816081B
+
+Key = 00000000000000000000000000000000
Nonce = 0000000000000000
Out = E28A5FA4A67F8C5DEFED3E6FB7303486AA8427D31419A729572D777953491120B64AB8E72B8DEB85CD6AEA7CB6089A101824BEEB08814A428AAB1FA2C816081B