diff options
author | SimCog <simon.cogliani@tanker.io> | 2016-06-14 18:21:10 +0200 |
---|---|---|
committer | SimCog <simon.cogliani@tanker.io> | 2016-06-18 01:06:21 +0200 |
commit | 00337c4ea2af6b1727be0bdf9b719c98760a14fd (patch) | |
tree | adc8b6f68311b2c9649bdb84766f22f99d2424db /src/lib | |
parent | 6816c9e71e01432792a997ad9a5d561b9cd94a48 (diff) |
Adding StreamCipher::seek interface, supporting seek in ChaCha, and also adding ChaCha8 support
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/prov/openssl/openssl_rc4.cpp | 5 | ||||
-rw-r--r-- | src/lib/stream/chacha/chacha.cpp | 28 | ||||
-rw-r--r-- | src/lib/stream/chacha/chacha.h | 4 | ||||
-rw-r--r-- | src/lib/stream/ctr/ctr.cpp | 4 | ||||
-rw-r--r-- | src/lib/stream/ctr/ctr.h | 2 | ||||
-rw-r--r-- | src/lib/stream/ofb/ofb.cpp | 5 | ||||
-rw-r--r-- | src/lib/stream/ofb/ofb.h | 2 | ||||
-rw-r--r-- | src/lib/stream/rc4/rc4.cpp | 4 | ||||
-rw-r--r-- | src/lib/stream/rc4/rc4.h | 2 | ||||
-rw-r--r-- | src/lib/stream/salsa20/salsa20.cpp | 4 | ||||
-rw-r--r-- | src/lib/stream/salsa20/salsa20.h | 2 | ||||
-rw-r--r-- | src/lib/stream/stream_cipher.h | 6 |
12 files changed, 64 insertions, 4 deletions
diff --git a/src/lib/prov/openssl/openssl_rc4.cpp b/src/lib/prov/openssl/openssl_rc4.cpp index e36535e08..070cdb14d 100644 --- a/src/lib/prov/openssl/openssl_rc4.cpp +++ b/src/lib/prov/openssl/openssl_rc4.cpp @@ -45,6 +45,11 @@ class OpenSSL_RC4 : public StreamCipher explicit OpenSSL_RC4(size_t skip = 0) : m_skip(skip) { clear(); } ~OpenSSL_RC4() { clear(); } + + void seek(u64bit) override + { + throw Exception("RC4 does not support seeking"); + } private: void cipher(const byte in[], byte out[], size_t length) override { diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp index ac81fd70d..40da93029 100644 --- a/src/lib/stream/chacha/chacha.cpp +++ b/src/lib/stream/chacha/chacha.cpp @@ -12,8 +12,8 @@ namespace Botan { ChaCha::ChaCha(size_t rounds) : m_rounds(rounds) { - if(m_rounds != 12 && m_rounds != 20) - throw Invalid_Argument("ChaCha only supports 12 or 20 rounds"); + if(m_rounds != 8 && m_rounds != 12 && m_rounds != 20) + throw Invalid_Argument("ChaCha only supports 8, 12 or 20 rounds"); } namespace { @@ -67,7 +67,6 @@ void chacha(byte output[64], const u32bit input[16], size_t rounds) store_le(x14 + input[14], output + 4 * 14); store_le(x15 + input[15], output + 4 * 15); } - } /* @@ -173,4 +172,27 @@ std::string ChaCha::name() const return "ChaCha(" + std::to_string(m_rounds) + ")"; } +void ChaCha::seek(u64bit offset) + { + if (m_state.size() == 0 && m_buffer.size() == 0) + { + throw Invalid_State("You have to setup the stream cipher (key and iv)"); + } + + m_position = offset % m_buffer.size(); + + u64bit counter = offset / m_buffer.size(); + + byte out[8]; + + store_le(counter, out); + + m_state[12] = load_le<u32bit>(out, 0); + m_state[13] += load_le<u32bit>(out, 1); + + chacha(m_buffer.data(), m_state.data(), m_rounds); + + ++m_state[12]; + m_state[13] += (m_state[12] == 0); + } } diff --git a/src/lib/stream/chacha/chacha.h b/src/lib/stream/chacha/chacha.h index ba93d6260..f8f42e41d 100644 --- a/src/lib/stream/chacha/chacha.h +++ b/src/lib/stream/chacha/chacha.h @@ -21,7 +21,7 @@ class BOTAN_DLL ChaCha final : public StreamCipher StreamCipher* clone() const override { return new ChaCha(m_rounds); } /** - * Currently only 12 or 20 rounds are supported, all others + * Currently only 8, 12 or 20 rounds are supported, all others * will throw an exception */ ChaCha(size_t rounds); @@ -42,6 +42,8 @@ class BOTAN_DLL ChaCha final : public StreamCipher std::string name() const override; + void seek(u64bit offset) override; + private: void key_schedule(const byte key[], size_t key_len) override; diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp index f5301c099..43609ba2d 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -125,4 +125,8 @@ void CTR_BE::increment_counter() m_pad_pos = 0; } +void CTR_BE::seek(u64bit) + { + throw Not_Implemented("CTR_BE::seek"); + } } diff --git a/src/lib/stream/ctr/ctr.h b/src/lib/stream/ctr/ctr.h index 003297b92..5d5556254 100644 --- a/src/lib/stream/ctr/ctr.h +++ b/src/lib/stream/ctr/ctr.h @@ -46,6 +46,8 @@ class BOTAN_DLL CTR_BE final : public StreamCipher explicit CTR_BE(BlockCipher* cipher); CTR_BE(BlockCipher* cipher, size_t ctr_size); + + void seek(u64bit offset) override; private: void key_schedule(const byte key[], size_t key_len) override; void increment_counter(); diff --git a/src/lib/stream/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp index e8cb463db..3337a0c14 100644 --- a/src/lib/stream/ofb/ofb.cpp +++ b/src/lib/stream/ofb/ofb.cpp @@ -73,4 +73,9 @@ void OFB::set_iv(const byte iv[], size_t iv_len) m_buf_pos = 0; } + +void OFB::seek(u64bit) + { + throw Exception("OFB does not support seeking"); + } } diff --git a/src/lib/stream/ofb/ofb.h b/src/lib/stream/ofb/ofb.h index fecd47d9d..127a06578 100644 --- a/src/lib/stream/ofb/ofb.h +++ b/src/lib/stream/ofb/ofb.h @@ -44,6 +44,8 @@ class BOTAN_DLL OFB final : public StreamCipher * @param cipher the underlying block cipher to use */ explicit OFB(BlockCipher* cipher); + + void seek(u64bit offset) override; private: void key_schedule(const byte key[], size_t key_len) override; diff --git a/src/lib/stream/rc4/rc4.cpp b/src/lib/stream/rc4/rc4.cpp index 895f38091..a4dea9e2b 100644 --- a/src/lib/stream/rc4/rc4.cpp +++ b/src/lib/stream/rc4/rc4.cpp @@ -113,4 +113,8 @@ void RC4::clear() */ RC4::RC4(size_t s) : m_SKIP(s) {} +void RC4::seek(u64bit) + { + throw Exception("RC4 does not support seeking"); + } } diff --git a/src/lib/stream/rc4/rc4.h b/src/lib/stream/rc4/rc4.h index f166a2772..88798fae6 100644 --- a/src/lib/stream/rc4/rc4.h +++ b/src/lib/stream/rc4/rc4.h @@ -39,6 +39,8 @@ class BOTAN_DLL RC4 final : public StreamCipher explicit RC4(size_t skip = 0); ~RC4() { clear(); } + + void seek(u64bit offset) override; private: void key_schedule(const byte[], size_t) override; void generate(); diff --git a/src/lib/stream/salsa20/salsa20.cpp b/src/lib/stream/salsa20/salsa20.cpp index 1d3fe3d28..f11fe5e59 100644 --- a/src/lib/stream/salsa20/salsa20.cpp +++ b/src/lib/stream/salsa20/salsa20.cpp @@ -227,4 +227,8 @@ void Salsa20::clear() m_position = 0; } +void Salsa20::seek(u64bit) + { + throw Not_Implemented("Salsa20::seek"); + } } diff --git a/src/lib/stream/salsa20/salsa20.h b/src/lib/stream/salsa20/salsa20.h index 7e75470da..8256ea4db 100644 --- a/src/lib/stream/salsa20/salsa20.h +++ b/src/lib/stream/salsa20/salsa20.h @@ -33,6 +33,8 @@ class BOTAN_DLL Salsa20 final : public StreamCipher void clear() override; std::string name() const override; StreamCipher* clone() const override { return new Salsa20; } + + void seek(u64bit offset) override; private: void key_schedule(const byte key[], size_t key_len) override; diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h index bff1fd1a6..56bd2d5d9 100644 --- a/src/lib/stream/stream_cipher.h +++ b/src/lib/stream/stream_cipher.h @@ -80,6 +80,12 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm */ virtual StreamCipher* clone() const = 0; + /** + * Set the offset and the state used later to generate the keystream + * @param offset the offset where we begin to generate the keystream + */ + virtual void seek(u64bit offset) = 0; + StreamCipher(); virtual ~StreamCipher(); }; |