aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-08-08 13:05:13 -0400
committerJack Lloyd <[email protected]>2018-08-08 13:05:13 -0400
commit9eb10b06036840822c03aec900a1e64f90e77181 (patch)
tree3f0eb3ec3739d8779d08ac51894a2e714390d038 /src
parentdfbc940e4dbc032b925e4ff54429a18e4923bbd2 (diff)
Add StreamCipher::default_iv_length
Diffstat (limited to 'src')
-rw-r--r--src/lib/stream/chacha/chacha.cpp2
-rw-r--r--src/lib/stream/chacha/chacha.h6
-rw-r--r--src/lib/stream/ctr/ctr.h2
-rw-r--r--src/lib/stream/ofb/ofb.h2
-rw-r--r--src/lib/stream/salsa20/salsa20.cpp15
-rw-r--r--src/lib/stream/salsa20/salsa20.h2
-rw-r--r--src/lib/stream/shake_cipher/shake_cipher.h2
-rw-r--r--src/lib/stream/stream_cipher.h6
-rw-r--r--src/tests/test_stream.cpp7
9 files changed, 33 insertions, 11 deletions
diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp
index 7ccc4293b..fac9a5a36 100644
--- a/src/lib/stream/chacha/chacha.cpp
+++ b/src/lib/stream/chacha/chacha.cpp
@@ -310,7 +310,7 @@ void ChaCha::seek(uint64_t offset)
verify_key_set(m_state.empty() == false);
// Find the block offset
- uint64_t counter = offset / 64;
+ const uint64_t counter = offset / 64;
uint8_t out[8];
diff --git a/src/lib/stream/chacha/chacha.h b/src/lib/stream/chacha/chacha.h
index a4f3e3b75..d0e131315 100644
--- a/src/lib/stream/chacha/chacha.h
+++ b/src/lib/stream/chacha/chacha.h
@@ -34,11 +34,15 @@ class BOTAN_PUBLIC_API(2,0) ChaCha final : public StreamCipher
void set_iv(const uint8_t iv[], size_t iv_len) override;
/*
- * ChaCha accepts 0, 8, or 12 byte IVs. The default IV is a 8 zero bytes.
+ * ChaCha accepts 0, 8, 12 or 24 byte IVs.
+ * The default IV is a 8 zero bytes.
* An IV of length 0 is treated the same as the default zero IV.
+ * An IV of length 24 selects XChaCha mode
*/
bool valid_iv_length(size_t iv_len) const override;
+ size_t default_iv_length() const override { return 24; }
+
Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(16, 32, 16);
diff --git a/src/lib/stream/ctr/ctr.h b/src/lib/stream/ctr/ctr.h
index c4c598161..3e0208363 100644
--- a/src/lib/stream/ctr/ctr.h
+++ b/src/lib/stream/ctr/ctr.h
@@ -23,6 +23,8 @@ class BOTAN_PUBLIC_API(2,0) CTR_BE final : public StreamCipher
void set_iv(const uint8_t iv[], size_t iv_len) override;
+ size_t default_iv_length() const override { return m_cipher->block_size(); }
+
bool valid_iv_length(size_t iv_len) const override
{ return (iv_len <= m_cipher->block_size()); }
diff --git a/src/lib/stream/ofb/ofb.h b/src/lib/stream/ofb/ofb.h
index e1f538984..afba43753 100644
--- a/src/lib/stream/ofb/ofb.h
+++ b/src/lib/stream/ofb/ofb.h
@@ -23,6 +23,8 @@ class BOTAN_PUBLIC_API(2,0) OFB final : public StreamCipher
void set_iv(const uint8_t iv[], size_t iv_len) override;
+ size_t default_iv_length() const override { return m_cipher->block_size(); }
+
bool valid_iv_length(size_t iv_len) const override
{ return (iv_len <= m_cipher->block_size()); }
diff --git a/src/lib/stream/salsa20/salsa20.cpp b/src/lib/stream/salsa20/salsa20.cpp
index 3ee6cf37e..ff24995ee 100644
--- a/src/lib/stream/salsa20/salsa20.cpp
+++ b/src/lib/stream/salsa20/salsa20.cpp
@@ -136,13 +136,6 @@ void Salsa20::initialize_state()
static const uint32_t SIGMA[] =
{ 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 };
- const uint32_t* CONSTANTS = (m_key.size() == 4) ? TAU : SIGMA;
-
- m_state[0] = CONSTANTS[0];
- m_state[5] = CONSTANTS[1];
- m_state[10] = CONSTANTS[2];
- m_state[15] = CONSTANTS[3];
-
m_state[1] = m_key[0];
m_state[2] = m_key[1];
m_state[3] = m_key[2];
@@ -150,6 +143,10 @@ void Salsa20::initialize_state()
if(m_key.size() == 4)
{
+ m_state[0] = TAU[0];
+ m_state[5] = TAU[1];
+ m_state[10] = TAU[2];
+ m_state[15] = TAU[3];
m_state[11] = m_key[0];
m_state[12] = m_key[1];
m_state[13] = m_key[2];
@@ -157,6 +154,10 @@ void Salsa20::initialize_state()
}
else
{
+ m_state[0] = SIGMA[0];
+ m_state[5] = SIGMA[1];
+ m_state[10] = SIGMA[2];
+ m_state[15] = SIGMA[3];
m_state[11] = m_key[4];
m_state[12] = m_key[5];
m_state[13] = m_key[6];
diff --git a/src/lib/stream/salsa20/salsa20.h b/src/lib/stream/salsa20/salsa20.h
index 090f9b18d..ea193273c 100644
--- a/src/lib/stream/salsa20/salsa20.h
+++ b/src/lib/stream/salsa20/salsa20.h
@@ -25,6 +25,8 @@ class BOTAN_PUBLIC_API(2,0) Salsa20 final : public StreamCipher
bool valid_iv_length(size_t iv_len) const override
{ return (iv_len == 0 || iv_len == 8 || iv_len == 24); }
+ size_t default_iv_length() const override { return 24; }
+
Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(16, 32, 16);
diff --git a/src/lib/stream/shake_cipher/shake_cipher.h b/src/lib/stream/shake_cipher/shake_cipher.h
index 12f2e780b..344ac965b 100644
--- a/src/lib/stream/shake_cipher/shake_cipher.h
+++ b/src/lib/stream/shake_cipher/shake_cipher.h
@@ -36,8 +36,6 @@ class BOTAN_PUBLIC_API(2,0) SHAKE_128_Cipher 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 == 0); }
-
/**
* In principle SHAKE can accept arbitrary length inputs, but this
* does not seem required for a stream cipher.
diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h
index 03ffcadd0..fee37f4e4 100644
--- a/src/lib/stream/stream_cipher.h
+++ b/src/lib/stream/stream_cipher.h
@@ -101,6 +101,12 @@ class BOTAN_PUBLIC_API(2,0) StreamCipher : public SymmetricAlgorithm
virtual void set_iv(const uint8_t iv[], size_t iv_len) = 0;
/**
+ * Return the default (preferred) nonce length
+ * If this function returns 0, then this cipher does not support nonces
+ */
+ virtual size_t default_iv_length() const { return 0; }
+
+ /**
* @param iv_len the length of the IV in bytes
* @return if the length is valid for this algorithm
*/
diff --git a/src/tests/test_stream.cpp b/src/tests/test_stream.cpp
index 5b61518f5..a77db5d39 100644
--- a/src/tests/test_stream.cpp
+++ b/src/tests/test_stream.cpp
@@ -57,6 +57,13 @@ class Stream_Cipher_Tests final : public Text_Based_Test
result.test_is_nonempty("provider", provider);
result.test_eq(provider, cipher->name(), algo);
+ result.confirm("default iv length is valid", cipher->valid_iv_length(cipher->default_iv_length()));
+
+ if(cipher->default_iv_length() == 0)
+ {
+ result.confirm("if default iv length is zero, no iv supported", nonce.size() == 0);
+ }
+
try
{
std::vector<uint8_t> buf(128);