From 7f6a017a61fc6ef97d9d7b37236df52d6170e7d6 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 15 Sep 2009 14:14:32 +0000 Subject: Add an implementation of Blue Midnight Wish (512 bit version only) --- src/engine/def_engine/lookup_hash.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/engine/def_engine') diff --git a/src/engine/def_engine/lookup_hash.cpp b/src/engine/def_engine/lookup_hash.cpp index 58136fc5a..9b2018736 100644 --- a/src/engine/def_engine/lookup_hash.cpp +++ b/src/engine/def_engine/lookup_hash.cpp @@ -22,6 +22,10 @@ #include #endif +#if defined(BOTAN_HAS_BMW_512) + #include +#endif + #if defined(BOTAN_HAS_FORK_256) #include #endif @@ -103,6 +107,11 @@ Default_Engine::find_hash(const SCAN_Name& request, return new CRC32; #endif +#if defined(BOTAN_HAS_BMW_512) + if(request.algo_name() == "BMW-512") + return new BMW_512; +#endif + #if defined(BOTAN_HAS_FORK_256) if(request.algo_name() == "FORK-256") return new FORK_256; -- cgit v1.2.3 From aea376790ba658b267aa9b1d5decf5735a7f727d Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 6 Oct 2009 16:04:20 +0000 Subject: Refactor Default_Engine::get_cipher so bits can be called from selftest --- src/engine/def_engine/def_eng.h | 5 + src/engine/def_engine/def_mode.cpp | 183 ++++++++++++++++++++----------------- 2 files changed, 104 insertions(+), 84 deletions(-) (limited to 'src/engine/def_engine') diff --git a/src/engine/def_engine/def_eng.h b/src/engine/def_engine/def_eng.h index 2d7145480..ba5bee8ef 100644 --- a/src/engine/def_engine/def_eng.h +++ b/src/engine/def_engine/def_eng.h @@ -78,6 +78,11 @@ class BOTAN_DLL Default_Engine : public Engine Algorithm_Factory&) const; }; +Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, + Cipher_Dir direction, + const std::string& mode, + const std::string& padding); + } #endif diff --git a/src/engine/def_engine/def_mode.cpp b/src/engine/def_engine/def_mode.cpp index 2b093a0a3..0c7a1a2e2 100644 --- a/src/engine/def_engine/def_mode.cpp +++ b/src/engine/def_engine/def_mode.cpp @@ -51,22 +51,22 @@ namespace { /** * Get a block cipher padding method by name */ -BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) +BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec, + const std::string& def_if_empty) { - SCAN_Name request(algo_spec); - #if defined(BOTAN_HAS_CIPHER_MODE_PADDING) - if(request.algo_name() == "PKCS7") + if(algo_spec == "NoPadding" || (algo_spec == "" && def_if_empty == "NoPadding")) + return new Null_Padding; + + if(algo_spec == "PKCS7" || (algo_spec == "" && def_if_empty == "PKCS7")) return new PKCS7_Padding; - if(request.algo_name() == "OneAndZeros") + if(algo_spec == "OneAndZeros") return new OneAndZeros_Padding; - if(request.algo_name() == "X9.23") + if(algo_spec == "X9.23") return new ANSI_X923_Padding; - if(request.algo_name() == "NoPadding") - return new Null_Padding; #endif throw Algorithm_Not_Found(algo_spec); @@ -74,58 +74,11 @@ BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) } -/* -* Get a cipher object -*/ -Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, - Cipher_Dir direction, - Algorithm_Factory& af) +Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, + Cipher_Dir direction, + const std::string& mode, + const std::string& padding) { - std::vector algo_parts = split_on(algo_spec, '/'); - if(algo_parts.empty()) - throw Invalid_Algorithm_Name(algo_spec); - - const std::string cipher_name = algo_parts[0]; - - // check if it is a stream cipher first (easy case) - const StreamCipher* stream_cipher = af.prototype_stream_cipher(cipher_name); - if(stream_cipher) - return new StreamCipher_Filter(stream_cipher->clone()); - - const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_name); - if(!block_cipher) - return 0; - - if(algo_parts.size() != 2 && algo_parts.size() != 3) - return 0; - - std::string mode = algo_parts[1]; - u32bit bits = 0; - - if(mode.find("CFB") != std::string::npos || - mode.find("EAX") != std::string::npos) - { - std::vector algo_info = parse_algorithm_name(mode); - mode = algo_info[0]; - if(algo_info.size() == 1) - bits = 8*block_cipher->BLOCK_SIZE; - else if(algo_info.size() == 2) - bits = to_u32bit(algo_info[1]); - else - throw Invalid_Algorithm_Name(algo_spec); - } - - std::string padding; - if(algo_parts.size() == 3) - padding = algo_parts[2]; - else - padding = (mode == "CBC") ? "PKCS7" : "NoPadding"; - - if(mode == "ECB" && padding == "CTS") - return 0; - else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding") - throw Invalid_Algorithm_Name(algo_spec); - #if defined(BOTAN_HAS_OFB) if(mode == "OFB") return new OFB(block_cipher->clone()); @@ -137,22 +90,14 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, #endif #if defined(BOTAN_HAS_ECB) - if(mode == "ECB") - { - if(direction == ENCRYPTION) - return new ECB_Encryption(block_cipher->clone(), get_bc_pad(padding)); - else - return new ECB_Decryption(block_cipher->clone(), get_bc_pad(padding)); - } -#endif - -#if defined(BOTAN_HAS_CFB) - if(mode == "CFB") + if(mode == "ECB" || mode == "") { if(direction == ENCRYPTION) - return new CFB_Encryption(block_cipher->clone(), bits); + return new ECB_Encryption(block_cipher->clone(), + get_bc_pad(padding, "NoPadding")); else - return new CFB_Decryption(block_cipher->clone(), bits); + return new ECB_Decryption(block_cipher->clone(), + get_bc_pad(padding, "NoPadding")); } #endif @@ -173,25 +118,15 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, #if defined(BOTAN_HAS_CBC) if(direction == ENCRYPTION) return new CBC_Encryption(block_cipher->clone(), - get_bc_pad(padding)); + get_bc_pad(padding, "PKCS7")); else return new CBC_Decryption(block_cipher->clone(), - get_bc_pad(padding)); + get_bc_pad(padding, "PKCS7")); #else return 0; #endif } -#if defined(BOTAN_HAS_EAX) - if(mode == "EAX") - { - if(direction == ENCRYPTION) - return new EAX_Encryption(block_cipher->clone(), bits); - else - return new EAX_Decryption(block_cipher->clone(), bits); - } -#endif - #if defined(BOTAN_HAS_XTS) if(mode == "XTS") { @@ -202,6 +137,86 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, } #endif + if(mode.find("CFB") != std::string::npos || + mode.find("EAX") != std::string::npos) + { + u32bit bits = 0; + + std::vector algo_info = parse_algorithm_name(mode); + std::string mode_name = algo_info[0]; + if(algo_info.size() == 1) + bits = 8*block_cipher->BLOCK_SIZE; + else if(algo_info.size() == 2) + bits = to_u32bit(algo_info[1]); + else + return 0; + +#if defined(BOTAN_HAS_CFB) + if(mode_name == "CFB") + { + if(direction == ENCRYPTION) + return new CFB_Encryption(block_cipher->clone(), bits); + else + return new CFB_Decryption(block_cipher->clone(), bits); + } +#endif + +#if defined(BOTAN_HAS_EAX) + if(mode_name == "EAX") + { + if(direction == ENCRYPTION) + return new EAX_Encryption(block_cipher->clone(), bits); + else + return new EAX_Decryption(block_cipher->clone(), bits); + } +#endif + } + + return 0; + } + +/* +* Get a cipher object +*/ +Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, + Cipher_Dir direction, + Algorithm_Factory& af) + { + std::vector algo_parts = split_on(algo_spec, '/'); + if(algo_parts.empty()) + throw Invalid_Algorithm_Name(algo_spec); + + const std::string cipher_name = algo_parts[0]; + + // check if it is a stream cipher first (easy case) + const StreamCipher* stream_cipher = af.prototype_stream_cipher(cipher_name); + if(stream_cipher) + return new StreamCipher_Filter(stream_cipher->clone()); + + const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_name); + if(!block_cipher) + return 0; + + if(algo_parts.size() != 2 && algo_parts.size() != 3) + return 0; + + std::string mode = algo_parts[1]; + + std::string padding; + if(algo_parts.size() == 3) + padding = algo_parts[2]; + else + padding = (mode == "CBC") ? "PKCS7" : "NoPadding"; + + if(mode == "ECB" && padding == "CTS") + return 0; + else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding") + throw Invalid_Algorithm_Name(algo_spec); + + Keyed_Filter* filt = get_cipher_mode(block_cipher, direction, mode, padding); + if(filt) + return filt; + throw Algorithm_Not_Found("get_mode: " + cipher_name + "/" + mode + "/" + padding); } -- cgit v1.2.3 From 01ea6faf1b9fb3ccd7233b1117e09c642c22d238 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 14 Oct 2009 23:13:23 +0000 Subject: Convert CTR_BE from a Filter to a StreamCipher. Must wrap in a StreamCipher_Filter to pass it directly to a Pipe now. --- checks/validate.dat | 7 ++ src/aont/package.cpp | 14 +--- src/cryptobox/cryptobox.cpp | 7 +- src/engine/def_engine/def_mode.cpp | 6 +- src/filters/algo_filt.cpp | 19 ++++- src/filters/filters.h | 7 ++ src/modes/ctr/ctr.cpp | 146 ------------------------------------- src/modes/ctr/ctr.h | 46 ------------ src/modes/ctr/info.txt | 15 ---- src/stream/ctr/ctr.cpp | 141 +++++++++++++++++++++++++++++++++++ src/stream/ctr/ctr.h | 49 +++++++++++++ src/stream/ctr/info.txt | 15 ++++ 12 files changed, 243 insertions(+), 229 deletions(-) delete mode 100644 src/modes/ctr/ctr.cpp delete mode 100644 src/modes/ctr/ctr.h delete mode 100644 src/modes/ctr/info.txt create mode 100644 src/stream/ctr/ctr.cpp create mode 100644 src/stream/ctr/ctr.h create mode 100644 src/stream/ctr/info.txt (limited to 'src/engine/def_engine') diff --git a/checks/validate.dat b/checks/validate.dat index de9db0b89..1ea88bcf3 100644 --- a/checks/validate.dat +++ b/checks/validate.dat @@ -23655,6 +23655,13 @@ DC7E84BFDA79164B7ECD8486985D38604FEBDC6740D20B3AC88F6AD82A4FB08D\ 5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE:\ 2B7E151628AED2A6ABF7158809CF4F3C:F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +# Test with 15 byte IV (last byte implicit zero) +AE2D8A571E03AC9C9EB76FAC45AF8E51\ +30C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710:\ +9806F66B7970FDFF8617187BB9FFFDFF\ +5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE:\ +2B7E151628AED2A6ABF7158809CF4F3C:F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF + 6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E51\ 30C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710:\ 1ABC932417521CA24F2B0459FE7E6E0B090339EC0AA6FAEFD5CCC2C6F4CE8E94\ 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 -#include +#include #include #include #include @@ -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/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 #include #include -#include +#include #include -#include #include #include #include @@ -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..120489b38 100644 --- a/src/engine/def_engine/def_mode.cpp +++ b/src/engine/def_engine/def_mode.cpp @@ -32,7 +32,7 @@ #include #endif -#if defined(BOTAN_HAS_CTR) +#if defined(BOTAN_HAS_CTR_BE) #include #endif @@ -84,9 +84,9 @@ Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, return 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 9a469b2d8..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); } /* diff --git a/src/filters/filters.h b/src/filters/filters.h index 418caf0aa..208332a56 100644 --- a/src/filters/filters.h +++ b/src/filters/filters.h @@ -73,6 +73,13 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter */ StreamCipher_Filter(StreamCipher* cipher_obj); + /** + * 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 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 -#include -#include - -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 -#include - -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 counter, enc_buffer; - u32bit position; - }; - -} - -#endif diff --git a/src/modes/ctr/info.txt b/src/modes/ctr/info.txt deleted file mode 100644 index cb291a2c1..000000000 --- a/src/modes/ctr/info.txt +++ /dev/null @@ -1,15 +0,0 @@ -realname "CTR block cipher mode" - -define CTR - -load_on auto - - -ctr.cpp -ctr.h - - - -modes - - 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 +#include + +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 +#include + +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 counter, buffer; + u32bit position; + }; + +} + +#endif diff --git a/src/stream/ctr/info.txt b/src/stream/ctr/info.txt new file mode 100644 index 000000000..53ab0afa5 --- /dev/null +++ b/src/stream/ctr/info.txt @@ -0,0 +1,15 @@ +realname "CTR mode" + +define CTR_BE + +load_on auto + + +ctr.cpp +ctr.h + + + +stream + + -- cgit v1.2.3 From 1d54dbb30e97097ef74b302032430a97e56fb328 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 14 Oct 2009 23:23:29 +0000 Subject: Similiar treatment for OFB which is also just a plain stream cipher --- src/engine/def_engine/def_mode.cpp | 2 +- src/modes/ofb/info.txt | 14 ------ src/modes/ofb/ofb.cpp | 66 -------------------------- src/modes/ofb/ofb.h | 33 ------------- src/stream/ctr/info.txt | 1 + src/stream/ofb/info.txt | 15 ++++++ src/stream/ofb/ofb.cpp | 97 ++++++++++++++++++++++++++++++++++++++ src/stream/ofb/ofb.h | 48 +++++++++++++++++++ 8 files changed, 162 insertions(+), 114 deletions(-) delete mode 100644 src/modes/ofb/info.txt delete mode 100644 src/modes/ofb/ofb.cpp delete mode 100644 src/modes/ofb/ofb.h create mode 100644 src/stream/ofb/info.txt create mode 100644 src/stream/ofb/ofb.cpp create mode 100644 src/stream/ofb/ofb.h (limited to 'src/engine/def_engine') diff --git a/src/engine/def_engine/def_mode.cpp b/src/engine/def_engine/def_mode.cpp index 120489b38..b7373ef84 100644 --- a/src/engine/def_engine/def_mode.cpp +++ b/src/engine/def_engine/def_mode.cpp @@ -81,7 +81,7 @@ 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_BE) diff --git a/src/modes/ofb/info.txt b/src/modes/ofb/info.txt deleted file mode 100644 index 3cba4151e..000000000 --- a/src/modes/ofb/info.txt +++ /dev/null @@ -1,14 +0,0 @@ -realname "OFB block cipher mode" - -define OFB - -load_on auto - - -ofb.cpp -ofb.h - - - -block - 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 -#include -#include - -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 -#include - -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/ctr/info.txt b/src/stream/ctr/info.txt index 53ab0afa5..04d14518a 100644 --- a/src/stream/ctr/info.txt +++ b/src/stream/ctr/info.txt @@ -10,6 +10,7 @@ ctr.h +block stream diff --git a/src/stream/ofb/info.txt b/src/stream/ofb/info.txt new file mode 100644 index 000000000..444fe0ffe --- /dev/null +++ b/src/stream/ofb/info.txt @@ -0,0 +1,15 @@ +realname "OFB block cipher mode" + +define OFB + +load_on auto + + +ofb.cpp +ofb.h + + + +block +stream + 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 +#include +#include + +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 +#include + +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 buffer; + u32bit position; + }; + +} + +#endif -- cgit v1.2.3