diff options
author | lloyd <[email protected]> | 2009-10-15 16:49:26 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-10-15 16:49:26 +0000 |
commit | d81a2a302f5405d18875d8e23193bd2fbd182d3b (patch) | |
tree | b2ed5fd6703cb7afadefb524ac42a85b759896f0 /src | |
parent | da210a5de236583baa530d8500a3da9f80b635fd (diff) | |
parent | 1d54dbb30e97097ef74b302032430a97e56fb328 (diff) |
merge of '5cfca720d4ca8d1e8f6946c7d9b4a8a6943094d0'
and '8cc9c08544c0f1f1dba7c7a8da51d1657b1c7df8'
Diffstat (limited to 'src')
27 files changed, 445 insertions, 428 deletions
diff --git a/src/aont/package.cpp b/src/aont/package.cpp index 6c6b56865..37bad46c8 100644 --- a/src/aont/package.cpp +++ b/src/aont/package.cpp @@ -7,7 +7,7 @@ */ #include <botan/package.h> -#include <botan/pipe.h> +#include <botan/filters.h> #include <botan/ctr.h> #include <botan/loadstor.h> #include <botan/xor_buf.h> @@ -29,12 +29,7 @@ void package(RandomNumberGenerator& rng, SymmetricKey package_key(rng, cipher->BLOCK_SIZE); - // takes ownership of cipher object - Keyed_Filter* ctr_mode = new CTR_BE(cipher, - package_key, - InitializationVector(all_zeros)); - - Pipe pipe(ctr_mode); + Pipe pipe(new StreamCipher_Filter(new CTR_BE(cipher), package_key)); pipe.process_msg(input, input_len); pipe.read(output, pipe.remaining()); @@ -113,10 +108,7 @@ void unpackage(BlockCipher* cipher, xor_buf(&package_key[0], buf, cipher->BLOCK_SIZE); } - // takes ownership of cipher object - Pipe pipe(new CTR_BE(cipher, - SymmetricKey(package_key), - InitializationVector(all_zeros))); + Pipe pipe(new StreamCipher_Filter(new CTR_BE(cipher), package_key)); pipe.process_msg(input, input_len - cipher->BLOCK_SIZE); diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp index 6e61baa59..41c9cd10c 100644 --- a/src/benchmark/benchmark.cpp +++ b/src/benchmark/benchmark.cpp @@ -85,7 +85,7 @@ bench_stream_cipher(StreamCipher* stream_cipher, while(nanoseconds_used < nanoseconds_max) { - stream_cipher->encrypt(buf, buf_len); + stream_cipher->cipher1(buf, buf_len); ++reps; nanoseconds_used = timer.clock() - start; } diff --git a/src/block/lion/lion.cpp b/src/block/lion/lion.cpp index 83c1e3aa3..0ed7b2630 100644 --- a/src/block/lion/lion.cpp +++ b/src/block/lion/lion.cpp @@ -22,7 +22,7 @@ void Lion::encrypt_n(const byte in[], byte out[], u32bit blocks) const { xor_buf(buffer, in, key1, LEFT_SIZE); cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); + cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); hash->update(out + LEFT_SIZE, RIGHT_SIZE); hash->final(buffer); @@ -30,7 +30,7 @@ void Lion::encrypt_n(const byte in[], byte out[], u32bit blocks) const xor_buf(buffer, out, key2, LEFT_SIZE); cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE); + cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE); in += BLOCK_SIZE; out += BLOCK_SIZE; @@ -48,7 +48,7 @@ void Lion::decrypt_n(const byte in[], byte out[], u32bit blocks) const { xor_buf(buffer, in, key2, LEFT_SIZE); cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); + cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); hash->update(out + LEFT_SIZE, RIGHT_SIZE); hash->final(buffer); @@ -56,7 +56,7 @@ void Lion::decrypt_n(const byte in[], byte out[], u32bit blocks) const xor_buf(buffer, out, key1, LEFT_SIZE); cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE); + cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE); in += BLOCK_SIZE; out += BLOCK_SIZE; diff --git a/src/cryptobox/cryptobox.cpp b/src/cryptobox/cryptobox.cpp index c27bbaffa..ba7553c55 100644 --- a/src/cryptobox/cryptobox.cpp +++ b/src/cryptobox/cryptobox.cpp @@ -8,9 +8,8 @@ #include <botan/cryptobox.h> #include <botan/filters.h> #include <botan/pipe.h> -#include <botan/serpent.h> +#include <botan/lookup.h> #include <botan/sha2_64.h> -#include <botan/ctr.h> #include <botan/hmac.h> #include <botan/pbkdf2.h> #include <botan/pem.h> @@ -59,7 +58,7 @@ std::string encrypt(const byte input[], u32bit input_len, InitializationVector iv(mk.begin() + CIPHER_KEY_LEN + MAC_KEY_LEN, CIPHER_IV_LEN); - Pipe pipe(new CTR_BE(new Serpent, cipher_key, iv), + Pipe pipe(get_cipher("Serpent/CTR-BE", cipher_key, iv, ENCRYPTION), new Fork( 0, new MAC_Filter(new HMAC(new SHA_512), @@ -121,7 +120,7 @@ std::string decrypt(const byte input[], u32bit input_len, CIPHER_IV_LEN); Pipe pipe(new Fork( - new CTR_BE(new Serpent, cipher_key, iv), + get_cipher("Serpent/CTR-BE", cipher_key, iv, ENCRYPTION), new MAC_Filter(new HMAC(new SHA_512), mac_key, MAC_OUTPUT_LEN))); diff --git a/src/engine/def_engine/def_mode.cpp b/src/engine/def_engine/def_mode.cpp index 0c7a1a2e2..b7373ef84 100644 --- a/src/engine/def_engine/def_mode.cpp +++ b/src/engine/def_engine/def_mode.cpp @@ -32,7 +32,7 @@ #include <botan/ofb.h> #endif -#if defined(BOTAN_HAS_CTR) +#if defined(BOTAN_HAS_CTR_BE) #include <botan/ctr.h> #endif @@ -81,12 +81,12 @@ Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, { #if defined(BOTAN_HAS_OFB) if(mode == "OFB") - return new OFB(block_cipher->clone()); + return new StreamCipher_Filter(new OFB(block_cipher->clone())); #endif -#if defined(BOTAN_HAS_CTR) +#if defined(BOTAN_HAS_CTR_BE) if(mode == "CTR-BE") - return new CTR_BE(block_cipher->clone()); + return new StreamCipher_Filter(new CTR_BE(block_cipher->clone())); #endif #if defined(BOTAN_HAS_ECB) diff --git a/src/filters/algo_filt.cpp b/src/filters/algo_filt.cpp index 3268276a6..51bf92380 100644 --- a/src/filters/algo_filt.cpp +++ b/src/filters/algo_filt.cpp @@ -14,20 +14,31 @@ namespace Botan { /* * StreamCipher_Filter Constructor */ -StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher) : buffer(DEFAULT_BUFFERSIZE) { - Algorithm_Factory& af = global_state().algorithm_factory(); - cipher = af.make_stream_cipher(sc_name); + cipher = stream_cipher; } /* * StreamCipher_Filter Constructor */ -StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher) : +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher, + const SymmetricKey& key) : buffer(DEFAULT_BUFFERSIZE) { cipher = stream_cipher; + cipher->set_key(key); + } + +/* +* StreamCipher_Filter Constructor +*/ +StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : + buffer(DEFAULT_BUFFERSIZE) + { + Algorithm_Factory& af = global_state().algorithm_factory(); + cipher = af.make_stream_cipher(sc_name); } /* @@ -47,7 +58,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, */ void StreamCipher_Filter::set_iv(const InitializationVector& iv) { - cipher->resync(iv.begin(), iv.length()); + cipher->set_iv(iv.begin(), iv.length()); } /* @@ -58,7 +69,7 @@ void StreamCipher_Filter::write(const byte input[], u32bit length) while(length) { u32bit copied = std::min(length, buffer.size()); - cipher->encrypt(input, buffer, copied); + cipher->cipher(input, buffer, copied); send(buffer, copied); input += copied; length -= copied; diff --git a/src/filters/filters.h b/src/filters/filters.h index 964be0bd8..208332a56 100644 --- a/src/filters/filters.h +++ b/src/filters/filters.h @@ -44,18 +44,8 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter */ void write(const byte input[], u32bit input_len); - /** - * Seek in the stream. - * @param position the position to seek ahead - */ - void seek(u32bit position) { cipher->seek(position); } - - /** - * Find out whether the cipher underlying this filter supports - * resyncing. - * @return true if the cipher supports resyncing - */ - bool supports_resync() const { return (cipher->IV_LENGTH != 0); } + bool valid_iv_length(u32bit iv_len) + { return cipher->valid_iv_length(iv_len); } /** * Set the initialization vector for this filter. @@ -85,6 +75,13 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter /** * Construct a stream cipher filter. + * @param cipher_obj a cipher object to use + * @param key the key to use inside this filter + */ + StreamCipher_Filter(StreamCipher* cipher_obj, const SymmetricKey& key); + + /** + * Construct a stream cipher filter. * @param cipher the name of the desired cipher */ StreamCipher_Filter(const std::string& cipher); diff --git a/src/modes/ctr/ctr.cpp b/src/modes/ctr/ctr.cpp deleted file mode 100644 index d458d7848..000000000 --- a/src/modes/ctr/ctr.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* -* CTR Mode -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/ctr.h> -#include <botan/xor_buf.h> -#include <algorithm> - -namespace Botan { - -namespace { - -const u32bit PARALLEL_BLOCKS = BOTAN_PARALLEL_BLOCKS_CTR; - -} - -/* -* CTR-BE Constructor -*/ -CTR_BE::CTR_BE(BlockCipher* ciph) : cipher(ciph) - { - position = 0; - - counter.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); - enc_buffer.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); - } - -/* -* CTR-BE Constructor -*/ -CTR_BE::CTR_BE(BlockCipher* ciph, const SymmetricKey& key, - const InitializationVector& iv) : - cipher(ciph) - { - position = 0; - - counter.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); - enc_buffer.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS); - - cipher->set_key(key); - set_iv(iv); - } - -/* -* CTR_BE Destructor -*/ -CTR_BE::~CTR_BE() - { - delete cipher; - } - -/* -* Return the name of this type -*/ -std::string CTR_BE::name() const - { - return ("CTR-BE/" + cipher->name()); - } - -/* -* Set CTR-BE IV -*/ -void CTR_BE::set_iv(const InitializationVector& iv) - { - const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; - - if(iv.length() != BLOCK_SIZE) - throw Invalid_IV_Length(name(), iv.length()); - - enc_buffer.clear(); - position = 0; - - counter.copy(0, iv.begin(), iv.length()); - - for(u32bit i = 1; i != PARALLEL_BLOCKS; ++i) - { - counter.copy(i*BLOCK_SIZE, - counter.begin() + (i-1)*BLOCK_SIZE, BLOCK_SIZE); - - for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j) - if(++counter[i*BLOCK_SIZE+j]) - break; - } - - cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS); - } - -/* -* CTR-BE Encryption/Decryption -*/ -void CTR_BE::write(const byte input[], u32bit length) - { - u32bit copied = std::min(enc_buffer.size() - position, length); - xor_buf(enc_buffer + position, input, copied); - send(enc_buffer + position, copied); - input += copied; - length -= copied; - position += copied; - - if(position == enc_buffer.size()) - increment_counter(); - - while(length >= enc_buffer.size()) - { - xor_buf(enc_buffer, input, enc_buffer.size()); - send(enc_buffer, enc_buffer.size()); - - input += enc_buffer.size(); - length -= enc_buffer.size(); - increment_counter(); - } - - xor_buf(enc_buffer + position, input, length); - send(enc_buffer + position, length); - position += length; - } - -/* -* Increment the counter and update the buffer -*/ -void CTR_BE::increment_counter() - { - for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) - { - byte* this_ctr = counter + i*cipher->BLOCK_SIZE; - - byte last_byte = this_ctr[cipher->BLOCK_SIZE-1]; - last_byte += PARALLEL_BLOCKS; - - if(this_ctr[cipher->BLOCK_SIZE-1] > last_byte) - for(s32bit j = cipher->BLOCK_SIZE - 2; j >= 0; --j) - if(++this_ctr[j]) - break; - - this_ctr[cipher->BLOCK_SIZE-1] = last_byte; - } - - cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS); - - position = 0; - } - -} diff --git a/src/modes/ctr/ctr.h b/src/modes/ctr/ctr.h deleted file mode 100644 index 1948ffe48..000000000 --- a/src/modes/ctr/ctr.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* CTR Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_COUNTER_MODE_H__ -#define BOTAN_COUNTER_MODE_H__ - -#include <botan/key_filt.h> -#include <botan/block_cipher.h> - -namespace Botan { - -/* -* CTR-BE Mode -*/ -class BOTAN_DLL CTR_BE : public Keyed_Filter - { - public: - std::string name() const; - - void set_iv(const InitializationVector&); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(u32bit key_len) const - { return cipher->valid_keylength(key_len); } - - CTR_BE(BlockCipher*); - CTR_BE(BlockCipher*, const SymmetricKey&, const InitializationVector&); - - ~CTR_BE(); - private: - void write(const byte[], u32bit); - void increment_counter(); - - BlockCipher* cipher; - SecureVector<byte> counter, enc_buffer; - u32bit position; - }; - -} - -#endif diff --git a/src/modes/ofb/ofb.cpp b/src/modes/ofb/ofb.cpp deleted file mode 100644 index cb40fdeaa..000000000 --- a/src/modes/ofb/ofb.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* OFB Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/ofb.h> -#include <botan/xor_buf.h> -#include <algorithm> - -namespace Botan { - -/* -* OFB Constructor -*/ -OFB::OFB(BlockCipher* ciph) : - BlockCipherMode(ciph, "OFB", ciph->BLOCK_SIZE, 2) - { - } - -/* -* OFB Constructor -*/ -OFB::OFB(BlockCipher* ciph, const SymmetricKey& key, - const InitializationVector& iv) : - BlockCipherMode(ciph, "OFB", ciph->BLOCK_SIZE, 2) - { - set_key(key); - set_iv(iv); - } - -/* -* OFB Encryption/Decryption -*/ -void OFB::write(const byte input[], u32bit length) - { - u32bit copied = std::min(BLOCK_SIZE - position, length); - xor_buf(buffer, input, state + position, copied); - send(buffer, copied); - input += copied; - length -= copied; - position += copied; - - if(position == BLOCK_SIZE) - { - cipher->encrypt(state); - position = 0; - } - - while(length >= BLOCK_SIZE) - { - xor_buf(buffer, input, state, BLOCK_SIZE); - send(buffer, BLOCK_SIZE); - - input += BLOCK_SIZE; - length -= BLOCK_SIZE; - cipher->encrypt(state); - } - - xor_buf(buffer, input, state + position, length); - send(buffer, length); - position += length; - } - -} diff --git a/src/modes/ofb/ofb.h b/src/modes/ofb/ofb.h deleted file mode 100644 index a3aadc137..000000000 --- a/src/modes/ofb/ofb.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* OFB Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_OUTPUT_FEEDBACK_MODE_H__ -#define BOTAN_OUTPUT_FEEDBACK_MODE_H__ - -#include <botan/modebase.h> -#include <botan/block_cipher.h> - -namespace Botan { - -/* -* OFB Mode -*/ -class BOTAN_DLL OFB : public BlockCipherMode - { - public: - OFB(BlockCipher* cipher); - - OFB(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv); - private: - void write(const byte[], u32bit); - }; - -} - -#endif diff --git a/src/stream/arc4/arc4.h b/src/stream/arc4/arc4.h index aa2cea7fe..3f92fa914 100644 --- a/src/stream/arc4/arc4.h +++ b/src/stream/arc4/arc4.h @@ -19,13 +19,16 @@ namespace Botan { class BOTAN_DLL ARC4 : public StreamCipher { public: + void cipher(const byte in[], byte out[], u32bit length); + void clear() throw(); std::string name() const; + StreamCipher* clone() const { return new ARC4(SKIP); } + ARC4(u32bit = 0); ~ARC4() { clear(); } private: - void cipher(const byte[], byte[], u32bit); void key_schedule(const byte[], u32bit); void generate(); diff --git a/src/stream/ctr/ctr.cpp b/src/stream/ctr/ctr.cpp new file mode 100644 index 000000000..5ef5e447f --- /dev/null +++ b/src/stream/ctr/ctr.cpp @@ -0,0 +1,141 @@ +/* +* CTR-BE Mode Cipher +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/ctr.h> +#include <botan/xor_buf.h> + +namespace Botan { + +/* +* CTR-BE Constructor +*/ + +CTR_BE::CTR_BE(BlockCipher* ciph) : + StreamCipher(ciph->MINIMUM_KEYLENGTH, + ciph->MAXIMUM_KEYLENGTH, + ciph->KEYLENGTH_MULTIPLE), + permutation(ciph) + { + position = 0; + + counter.create(permutation->BLOCK_SIZE * BOTAN_PARALLEL_BLOCKS_CTR); + buffer.create(permutation->BLOCK_SIZE * BOTAN_PARALLEL_BLOCKS_CTR); + } + +/* +* CTR_BE Destructor +*/ +CTR_BE::~CTR_BE() + { + delete permutation; + } + +/* +* Zeroize +*/ +void CTR_BE::clear() throw() + { + permutation->clear(); + buffer.clear(); + counter.clear(); + position = 0; + } + +/* +* Set the key +*/ +void CTR_BE::key_schedule(const byte key[], u32bit key_len) + { + permutation->set_key(key, key_len); + + // Set a default all-zeros IV + set_iv(0, 0); + } + +/* +* Return the name of this type +*/ +std::string CTR_BE::name() const + { + return ("CTR-BE(" + permutation->name() + ")"); + } + +/* +* CTR-BE Encryption/Decryption +*/ +void CTR_BE::cipher(const byte in[], byte out[], u32bit length) + { + while(length >= buffer.size() - position) + { + xor_buf(out, in, buffer.begin() + position, buffer.size() - position); + length -= (buffer.size() - position); + in += (buffer.size() - position); + out += (buffer.size() - position); + increment_counter(); + } + xor_buf(out, in, buffer.begin() + position, length); + position += length; + } + +/* +* Set CTR-BE IV +*/ +void CTR_BE::set_iv(const byte iv[], u32bit iv_len) + { + if(!valid_iv_length(iv_len)) + throw Invalid_IV_Length(name(), iv_len); + + const u32bit BLOCK_SIZE = permutation->BLOCK_SIZE; + + counter.clear(); + + counter.copy(0, iv, iv_len); + + const u32bit PARALLEL_BLOCKS = counter.size() / BLOCK_SIZE; + + for(u32bit i = 1; i != PARALLEL_BLOCKS; ++i) + { + counter.copy(i*BLOCK_SIZE, + counter.begin() + (i-1)*BLOCK_SIZE, BLOCK_SIZE); + + for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j) + if(++counter[i*BLOCK_SIZE+j]) + break; + } + + permutation->encrypt_n(counter, buffer, PARALLEL_BLOCKS); + position = 0; + } + +/* +* Increment the counter and update the buffer +*/ +void CTR_BE::increment_counter() + { + const u32bit PARALLEL_BLOCKS = counter.size() / permutation->BLOCK_SIZE; + + for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) + { + byte* this_ctr = counter + i*permutation->BLOCK_SIZE; + + byte last_byte = this_ctr[permutation->BLOCK_SIZE-1]; + last_byte += PARALLEL_BLOCKS; + + if(this_ctr[permutation->BLOCK_SIZE-1] > last_byte) + for(s32bit j = permutation->BLOCK_SIZE - 2; j >= 0; --j) + if(++this_ctr[j]) + break; + + this_ctr[permutation->BLOCK_SIZE-1] = last_byte; + } + + permutation->encrypt_n(counter, buffer, PARALLEL_BLOCKS); + + position = 0; + } + +} diff --git a/src/stream/ctr/ctr.h b/src/stream/ctr/ctr.h new file mode 100644 index 000000000..f60f21b5a --- /dev/null +++ b/src/stream/ctr/ctr.h @@ -0,0 +1,49 @@ +/* +* CTR-BE Mode +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_CTR_BE_H__ +#define BOTAN_CTR_BE_H__ + +#include <botan/block_cipher.h> +#include <botan/stream_cipher.h> + +namespace Botan { + +/* +* CTR-BE (Counter, big-endian) +*/ +class BOTAN_DLL CTR_BE : public StreamCipher + { + public: + void cipher(const byte in[], byte out[], u32bit length); + + void set_iv(const byte iv[], u32bit iv_len); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len <= permutation->BLOCK_SIZE); } + + std::string name() const; + + CTR_BE* clone() const + { return new CTR_BE(permutation->clone()); } + + void clear() throw(); + + CTR_BE(BlockCipher*); + ~CTR_BE(); + private: + void key_schedule(const byte key[], u32bit key_len); + void increment_counter(); + + BlockCipher* permutation; + SecureVector<byte> counter, buffer; + u32bit position; + }; + +} + +#endif diff --git a/src/modes/ctr/info.txt b/src/stream/ctr/info.txt index cb291a2c1..04d14518a 100644 --- a/src/modes/ctr/info.txt +++ b/src/stream/ctr/info.txt @@ -1,6 +1,6 @@ -realname "CTR block cipher mode" +realname "CTR mode" -define CTR +define CTR_BE load_on auto @@ -10,6 +10,7 @@ ctr.h </add> <requires> -modes +block +stream </requires> diff --git a/src/stream/info.txt b/src/stream/info.txt index 295c73708..f8f4b22d5 100644 --- a/src/stream/info.txt +++ b/src/stream/info.txt @@ -6,7 +6,6 @@ define STREAM_CIPHER <add> stream_cipher.h -stream_cipher.cpp </add> <requires> diff --git a/src/modes/ofb/info.txt b/src/stream/ofb/info.txt index 3cba4151e..444fe0ffe 100644 --- a/src/modes/ofb/info.txt +++ b/src/stream/ofb/info.txt @@ -11,4 +11,5 @@ ofb.h <requires> block +stream </requires> diff --git a/src/stream/ofb/ofb.cpp b/src/stream/ofb/ofb.cpp new file mode 100644 index 000000000..577f61cbf --- /dev/null +++ b/src/stream/ofb/ofb.cpp @@ -0,0 +1,97 @@ +/* +* OFB Mode +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/ofb.h> +#include <botan/xor_buf.h> +#include <algorithm> + +namespace Botan { + +/* +* OFB Constructor +*/ +OFB::OFB(BlockCipher* ciph) : + StreamCipher(ciph->MINIMUM_KEYLENGTH, + ciph->MAXIMUM_KEYLENGTH, + ciph->KEYLENGTH_MULTIPLE), + permutation(ciph) + { + position = 0; + buffer.create(permutation->BLOCK_SIZE); + } + +/* +* OFB Destructor +*/ +OFB::~OFB() + { + delete permutation; + } + +/* +* Zeroize +*/ +void OFB::clear() throw() + { + permutation->clear(); + buffer.clear(); + position = 0; + } + +/* +* Set the key +*/ +void OFB::key_schedule(const byte key[], u32bit key_len) + { + permutation->set_key(key, key_len); + + // Set a default all-zeros IV + set_iv(0, 0); + } + +/* +* Return the name of this type +*/ +std::string OFB::name() const + { + return ("OFB(" + permutation->name() + ")"); + } + +/* +* CTR-BE Encryption/Decryption +*/ +void OFB::cipher(const byte in[], byte out[], u32bit length) + { + while(length >= buffer.size() - position) + { + xor_buf(out, in, buffer.begin() + position, buffer.size() - position); + length -= (buffer.size() - position); + in += (buffer.size() - position); + out += (buffer.size() - position); + permutation->encrypt(buffer); + position = 0; + } + xor_buf(out, in, buffer.begin() + position, length); + position += length; + } + +/* +* Set CTR-BE IV +*/ +void OFB::set_iv(const byte iv[], u32bit iv_len) + { + if(!valid_iv_length(iv_len)) + throw Invalid_IV_Length(name(), iv_len); + + buffer.clear(); + buffer.copy(0, iv, iv_len); + + permutation->encrypt(buffer); + position = 0; + } + +} diff --git a/src/stream/ofb/ofb.h b/src/stream/ofb/ofb.h new file mode 100644 index 000000000..5cd48716b --- /dev/null +++ b/src/stream/ofb/ofb.h @@ -0,0 +1,48 @@ +/* +* OFB Mode +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_OUTPUT_FEEDBACK_MODE_H__ +#define BOTAN_OUTPUT_FEEDBACK_MODE_H__ + +#include <botan/stream_cipher.h> +#include <botan/block_cipher.h> + +namespace Botan { + +/* +* OFB Mode +*/ +class BOTAN_DLL OFB : public StreamCipher + { + public: + void cipher(const byte in[], byte out[], u32bit length); + + void set_iv(const byte iv[], u32bit iv_len); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len <= permutation->BLOCK_SIZE); } + + std::string name() const; + + OFB* clone() const + { return new OFB(permutation->clone()); } + + void clear() throw(); + + OFB(BlockCipher*); + ~OFB(); + private: + void key_schedule(const byte key[], u32bit key_len); + + BlockCipher* permutation; + SecureVector<byte> buffer; + u32bit position; + }; + +} + +#endif diff --git a/src/stream/salsa20/salsa20.cpp b/src/stream/salsa20/salsa20.cpp index 9c7c811f0..a147cdb45 100644 --- a/src/stream/salsa20/salsa20.cpp +++ b/src/stream/salsa20/salsa20.cpp @@ -162,15 +162,15 @@ void Salsa20::key_schedule(const byte key[], u32bit length) } const byte ZERO[8] = { 0 }; - resync(ZERO, sizeof(ZERO)); + set_iv(ZERO, sizeof(ZERO)); } /* * Return the name of this type */ -void Salsa20::resync(const byte iv[], u32bit length) +void Salsa20::set_iv(const byte iv[], u32bit length) { - if(length != IV_LENGTH) + if(!valid_iv_length(length)) throw Invalid_IV_Length(name(), length); state[6] = load_le<u32bit>(iv, 0); @@ -207,7 +207,7 @@ void Salsa20::clear() throw() /* * Salsa20 Constructor */ -Salsa20::Salsa20() : StreamCipher(16, 32, 16, 8) +Salsa20::Salsa20() : StreamCipher(16, 32, 16) { clear(); } diff --git a/src/stream/salsa20/salsa20.h b/src/stream/salsa20/salsa20.h index 3dbfddb50..a3e9a3706 100644 --- a/src/stream/salsa20/salsa20.h +++ b/src/stream/salsa20/salsa20.h @@ -18,17 +18,21 @@ namespace Botan { class BOTAN_DLL Salsa20 : public StreamCipher { public: + void cipher(const byte in[], byte out[], u32bit length); + + void set_iv(const byte iv[], u32bit iv_len); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == 8); } + void clear() throw(); std::string name() const; StreamCipher* clone() const { return new Salsa20; } - void resync(const byte[], u32bit); - Salsa20(); ~Salsa20() { clear(); } private: - void cipher(const byte[], byte[], u32bit); - void key_schedule(const byte[], u32bit); + void key_schedule(const byte key[], u32bit key_len); SecureBuffer<u32bit, 16> state; diff --git a/src/stream/stream_cipher.cpp b/src/stream/stream_cipher.cpp deleted file mode 100644 index 68bb5d4f0..000000000 --- a/src/stream/stream_cipher.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/** -* Stream Cipher Default Implementation for IV and Seek -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/stream_cipher.h> - -namespace Botan { - -/* -* Default StreamCipher Resync Operation -*/ -void StreamCipher::resync(const byte[], u32bit length) - { - if(length) - throw Exception("The stream cipher " + name() + - " does not support resyncronization"); - } - -/* -* Default StreamCipher Seek Operation -*/ -void StreamCipher::seek(u32bit) - { - throw Exception("The stream cipher " + name() + " does not support seek()"); - } - -} diff --git a/src/stream/stream_cipher.h b/src/stream/stream_cipher.h index 8ea359131..d6abb37fc 100644 --- a/src/stream/stream_cipher.h +++ b/src/stream/stream_cipher.h @@ -18,53 +18,40 @@ namespace Botan { class BOTAN_DLL StreamCipher : public SymmetricAlgorithm { public: - const u32bit IV_LENGTH; - - /** - * Encrypt a message. - * @param i the plaintext - * @param o the byte array to hold the output, i.e. the ciphertext - * @param len the length of both i and o - */ - void encrypt(const byte i[], byte o[], u32bit len) { cipher(i, o, len); } - /** - * Decrypt a message. - * @param i the ciphertext to decrypt - * @param o the byte array to hold the output, i.e. the plaintext - * @param len the length of both i and o + * Encrypt or decrypt a message + * @param in the plaintext + * @param out the byte array to hold the output, i.e. the ciphertext + * @param len the length of both in and out in bytes */ - void decrypt(const byte i[], byte o[], u32bit len) { cipher(i, o, len); } + virtual void cipher(const byte in[], byte out[], u32bit len) = 0; /** - * Encrypt a message. - * @param in the plaintext as input, after the function has - * returned it will hold the ciphertext - - * @param len the length of in + * Encrypt or decrypt a message + * @param buf the plaintext / ciphertext + * @param len the length of buf in bytes */ - void encrypt(byte in[], u32bit len) { cipher(in, in, len); } - - /** - * Decrypt a message. - * @param in the ciphertext as input, after the function has - * returned it will hold the plaintext - * @param len the length of in - */ - void decrypt(byte in[], u32bit len) { cipher(in, in, len); } + void cipher1(byte buf[], u32bit len) + { cipher(buf, buf, len); } /** * Resync the cipher using the IV * @param iv the initialization vector * @param iv_len the length of the IV in bytes */ - virtual void resync(const byte iv[], u32bit iv_len); + virtual void set_iv(const byte[], u32bit iv_len) + { + if(iv_len) + throw Exception("The stream cipher " + name() + + " does not support resyncronization"); + } /** - * Seek ahead in the stream. - * @param len the length to seek ahead. + * @param iv_len the length of the IV in bytes + * @return if the length is valid for this algorithm */ - virtual void seek(u32bit len); + virtual bool valid_iv_length(u32bit iv_len) const + { return (iv_len == 0); } /** * Get a new object representing the same algorithm as *this @@ -76,15 +63,15 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm */ virtual void clear() throw() = 0; - StreamCipher(u32bit key_min, u32bit key_max = 0, - u32bit key_mod = 1, - u32bit iv_len = 0) : - SymmetricAlgorithm(key_min, key_max, key_mod), - IV_LENGTH(iv_len) {} + /** + * StreamCipher constructor + */ + StreamCipher(u32bit key_min, + u32bit key_max = 0, + u32bit key_mod = 1) : + SymmetricAlgorithm(key_min, key_max, key_mod) {} virtual ~StreamCipher() {} - private: - virtual void cipher(const byte[], byte[], u32bit) = 0; }; } diff --git a/src/stream/turing/turing.cpp b/src/stream/turing/turing.cpp index 1e2203480..8336a70a7 100644 --- a/src/stream/turing/turing.cpp +++ b/src/stream/turing/turing.cpp @@ -257,15 +257,15 @@ void Turing::key_schedule(const byte key[], u32bit length) S3[i] = (W3 & 0xFFFFFF00) | C3; } - resync(0, 0); + set_iv(0, 0); } /* * Resynchronization */ -void Turing::resync(const byte iv[], u32bit length) +void Turing::set_iv(const byte iv[], u32bit length) { - if(length % 4 != 0 || length > 16) + if(!valid_iv_length(length)) throw Invalid_IV_Length(name(), length); SecureVector<u32bit> IV(length / 4); diff --git a/src/stream/turing/turing.h b/src/stream/turing/turing.h index 455d3c612..59290f640 100644 --- a/src/stream/turing/turing.h +++ b/src/stream/turing/turing.h @@ -18,14 +18,18 @@ namespace Botan { class BOTAN_DLL Turing : public StreamCipher { public: + void cipher(const byte in[], byte out[], u32bit length); + void set_iv(const byte[], u32bit); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len % 4 == 0 && iv_len <= 16); } + void clear() throw(); std::string name() const { return "Turing"; } StreamCipher* clone() const { return new Turing; } Turing() : StreamCipher(4, 32, 4) { position = 0; } private: - void cipher(const byte[], byte[], u32bit); void key_schedule(const byte[], u32bit); - void resync(const byte[], u32bit); void generate(); static u32bit fixedS(u32bit); diff --git a/src/stream/wid_wake/wid_wake.cpp b/src/stream/wid_wake/wid_wake.cpp index 1dc0fd7f9..56f938fac 100644 --- a/src/stream/wid_wake/wid_wake.cpp +++ b/src/stream/wid_wake/wid_wake.cpp @@ -110,16 +110,17 @@ void WiderWake_41_BE::key_schedule(const byte key[], u32bit) T[X] = Z; position = 0; - const byte iv[8] = { 0 }; - resync(iv, 8); + + const byte ZEROS[8] = { 0 }; + set_iv(ZEROS, sizeof(ZEROS)); } /* * Resynchronization */ -void WiderWake_41_BE::resync(const byte iv[], u32bit length) +void WiderWake_41_BE::set_iv(const byte iv[], u32bit length) { - if(length != 8) + if(!valid_iv_length(length)) throw Invalid_IV_Length(name(), length); for(u32bit j = 0; j != 4; ++j) diff --git a/src/stream/wid_wake/wid_wake.h b/src/stream/wid_wake/wid_wake.h index 4720afdb2..a037a056e 100644 --- a/src/stream/wid_wake/wid_wake.h +++ b/src/stream/wid_wake/wid_wake.h @@ -18,14 +18,18 @@ namespace Botan { class BOTAN_DLL WiderWake_41_BE : public StreamCipher { public: + void cipher(const byte[], byte[], u32bit); + void set_iv(const byte[], u32bit); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == 8); } + void clear() throw(); std::string name() const { return "WiderWake4+1-BE"; } StreamCipher* clone() const { return new WiderWake_41_BE; } - WiderWake_41_BE() : StreamCipher(16, 16, 1, 8) {} + WiderWake_41_BE() : StreamCipher(16, 16, 1) {} private: - void cipher(const byte[], byte[], u32bit); void key_schedule(const byte[], u32bit); - void resync(const byte[], u32bit); void generate(u32bit); |