aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-09-28 18:15:52 +0000
committerlloyd <[email protected]>2008-09-28 18:15:52 +0000
commit983a8ecb42e844f89466d0ae52bba591d4fc4275 (patch)
treede01378ee9be0ba8bec28bc08d3bde6e422ff898 /modules
parentd59f6a2c9e797ee22c21b2d85c662e0fe8d1cf35 (diff)
Modularize cipher modes
Diffstat (limited to 'modules')
-rw-r--r--modules/modes/cbc/cbc.cpp157
-rw-r--r--modules/modes/cbc/cbc.h49
-rw-r--r--modules/modes/cbc/modinfo.txt10
-rw-r--r--modules/modes/cfb/cfb.cpp142
-rw-r--r--modules/modes/cfb/cfb.h45
-rw-r--r--modules/modes/cfb/modinfo.txt10
-rw-r--r--modules/modes/ctr/ctr.cpp74
-rw-r--r--modules/modes/ctr/ctr.h29
-rw-r--r--modules/modes/ctr/modinfo.txt10
-rw-r--r--modules/modes/cts/cts.cpp175
-rw-r--r--modules/modes/cts/cts.h46
-rw-r--r--modules/modes/cts/modinfo.txt10
-rw-r--r--modules/modes/eax/eax.cpp194
-rw-r--r--modules/modes/eax/eax.h72
-rw-r--r--modules/modes/eax/eax_dec.cpp126
-rw-r--r--modules/modes/eax/modinfo.txt11
-rw-r--r--modules/modes/ecb/ecb.cpp152
-rw-r--r--modules/modes/ecb/ecb.h57
-rw-r--r--modules/modes/ecb/modinfo.txt10
-rw-r--r--modules/modes/ofb/modinfo.txt10
-rw-r--r--modules/modes/ofb/ofb.cpp65
-rw-r--r--modules/modes/ofb/ofb.h28
22 files changed, 1482 insertions, 0 deletions
diff --git a/modules/modes/cbc/cbc.cpp b/modules/modes/cbc/cbc.cpp
new file mode 100644
index 000000000..9ad598bed
--- /dev/null
+++ b/modules/modes/cbc/cbc.cpp
@@ -0,0 +1,157 @@
+/*************************************************
+* CBC Mode Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/cbc.h>
+#include <botan/lookup.h>
+#include <botan/xor_buf.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* CBC Encryption Constructor *
+*************************************************/
+CBC_Encryption::CBC_Encryption(const std::string& cipher_name,
+ const std::string& padding_name) :
+ BlockCipherMode(cipher_name, "CBC", block_size_of(cipher_name)),
+ padder(get_bc_pad(padding_name))
+ {
+ if(!padder->valid_blocksize(BLOCK_SIZE))
+ throw Invalid_Block_Size(name(), padder->name());
+ }
+
+/*************************************************
+* CBC Encryption Constructor *
+*************************************************/
+CBC_Encryption::CBC_Encryption(const std::string& cipher_name,
+ const std::string& padding_name,
+ const SymmetricKey& key,
+ const InitializationVector& iv) :
+ BlockCipherMode(cipher_name, "CBC", block_size_of(cipher_name)),
+ padder(get_bc_pad(padding_name))
+ {
+ if(!padder->valid_blocksize(BLOCK_SIZE))
+ throw Invalid_Block_Size(name(), padder->name());
+ set_key(key);
+ set_iv(iv);
+ }
+
+/*************************************************
+* Encrypt in CBC mode *
+*************************************************/
+void CBC_Encryption::write(const byte input[], u32bit length)
+ {
+ while(length)
+ {
+ u32bit xored = std::min(BLOCK_SIZE - position, length);
+ xor_buf(state + position, input, xored);
+ input += xored;
+ length -= xored;
+ position += xored;
+ if(position == BLOCK_SIZE)
+ {
+ cipher->encrypt(state);
+ send(state, BLOCK_SIZE);
+ position = 0;
+ }
+ }
+ }
+
+/*************************************************
+* Finish encrypting in CBC mode *
+*************************************************/
+void CBC_Encryption::end_msg()
+ {
+ SecureVector<byte> padding(BLOCK_SIZE);
+ padder->pad(padding, padding.size(), position);
+ write(padding, padder->pad_bytes(BLOCK_SIZE, position));
+ if(position != 0)
+ throw Exception(name() + ": Did not pad to full blocksize");
+ }
+
+/*************************************************
+* Return a CBC mode name *
+*************************************************/
+std::string CBC_Encryption::name() const
+ {
+ return (cipher->name() + "/" + mode_name + "/" + padder->name());
+ }
+
+/*************************************************
+* CBC Decryption Constructor *
+*************************************************/
+CBC_Decryption::CBC_Decryption(const std::string& cipher_name,
+ const std::string& padding_name) :
+ BlockCipherMode(cipher_name, "CBC", block_size_of(cipher_name)),
+ padder(get_bc_pad(padding_name))
+ {
+ if(!padder->valid_blocksize(BLOCK_SIZE))
+ throw Invalid_Block_Size(name(), padder->name());
+ temp.create(BLOCK_SIZE);
+ }
+
+/*************************************************
+* CBC Decryption Constructor *
+*************************************************/
+CBC_Decryption::CBC_Decryption(const std::string& cipher_name,
+ const std::string& padding_name,
+ const SymmetricKey& key,
+ const InitializationVector& iv) :
+ BlockCipherMode(cipher_name, "CBC", block_size_of(cipher_name)),
+ padder(get_bc_pad(padding_name))
+ {
+ if(!padder->valid_blocksize(BLOCK_SIZE))
+ throw Invalid_Block_Size(name(), padder->name());
+ temp.create(BLOCK_SIZE);
+ set_key(key);
+ set_iv(iv);
+ }
+
+/*************************************************
+* Decrypt in CBC mode *
+*************************************************/
+void CBC_Decryption::write(const byte input[], u32bit length)
+ {
+ while(length)
+ {
+ if(position == BLOCK_SIZE)
+ {
+ cipher->decrypt(buffer, temp);
+ xor_buf(temp, state, BLOCK_SIZE);
+ send(temp, BLOCK_SIZE);
+ state = buffer;
+ position = 0;
+ }
+ u32bit added = std::min(BLOCK_SIZE - position, length);
+ buffer.copy(position, input, added);
+ input += added;
+ length -= added;
+ position += added;
+ }
+ }
+
+/*************************************************
+* Finish decrypting in CBC mode *
+*************************************************/
+void CBC_Decryption::end_msg()
+ {
+ if(position != BLOCK_SIZE)
+ throw Decoding_Error(name());
+ cipher->decrypt(buffer, temp);
+ xor_buf(temp, state, BLOCK_SIZE);
+ send(temp, padder->unpad(temp, BLOCK_SIZE));
+ state = buffer;
+ position = 0;
+ }
+
+/*************************************************
+* Return a CBC mode name *
+*************************************************/
+std::string CBC_Decryption::name() const
+ {
+ return (cipher->name() + "/" + mode_name + "/" + padder->name());
+ }
+
+}
diff --git a/modules/modes/cbc/cbc.h b/modules/modes/cbc/cbc.h
new file mode 100644
index 000000000..a0a30f90f
--- /dev/null
+++ b/modules/modes/cbc/cbc.h
@@ -0,0 +1,49 @@
+/*************************************************
+* CBC Mode Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_CBC_H__
+#define BOTAN_CBC_H__
+
+#include <botan/modebase.h>
+#include <botan/mode_pad.h>
+
+namespace Botan {
+
+/*************************************************
+* CBC Encryption *
+*************************************************/
+class BOTAN_DLL CBC_Encryption : public BlockCipherMode
+ {
+ public:
+ CBC_Encryption(const std::string&, const std::string&);
+ CBC_Encryption(const std::string&, const std::string&,
+ const SymmetricKey&, const InitializationVector&);
+ private:
+ std::string name() const;
+ void write(const byte[], u32bit);
+ void end_msg();
+ const BlockCipherModePaddingMethod* padder;
+ };
+
+/*************************************************
+* CBC Decryption *
+*************************************************/
+class BOTAN_DLL CBC_Decryption : public BlockCipherMode
+ {
+ public:
+ CBC_Decryption(const std::string&, const std::string&);
+ CBC_Decryption(const std::string&, const std::string&,
+ const SymmetricKey&, const InitializationVector&);
+ private:
+ std::string name() const;
+ void write(const byte[], u32bit);
+ void end_msg();
+ const BlockCipherModePaddingMethod* padder;
+ SecureVector<byte> temp;
+ };
+
+}
+
+#endif
diff --git a/modules/modes/cbc/modinfo.txt b/modules/modes/cbc/modinfo.txt
new file mode 100644
index 000000000..4ebc7730a
--- /dev/null
+++ b/modules/modes/cbc/modinfo.txt
@@ -0,0 +1,10 @@
+realname "CBC block cipher mode"
+
+define CBC
+
+load_on auto
+
+<add>
+cbc.cpp
+cbc.h
+</add>
diff --git a/modules/modes/cfb/cfb.cpp b/modules/modes/cfb/cfb.cpp
new file mode 100644
index 000000000..dbfbff6ae
--- /dev/null
+++ b/modules/modes/cfb/cfb.cpp
@@ -0,0 +1,142 @@
+/*************************************************
+* CFB Mode Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/cfb.h>
+#include <botan/lookup.h>
+#include <botan/parsing.h>
+#include <botan/xor_buf.h>
+#include <algorithm>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Check the feedback size *
+*************************************************/
+void check_feedback(u32bit BLOCK_SIZE, u32bit FEEDBACK_SIZE, u32bit bits,
+ const std::string& name)
+ {
+ if(FEEDBACK_SIZE == 0 || FEEDBACK_SIZE > BLOCK_SIZE || bits % 8 != 0)
+ throw Invalid_Argument(name + ": Invalid feedback size " +
+ to_string(bits));
+ }
+
+}
+
+/*************************************************
+* CFB Encryption Constructor *
+*************************************************/
+CFB_Encryption::CFB_Encryption(const std::string& cipher_name,
+ u32bit fback_bits) :
+ BlockCipherMode(cipher_name, "CFB", block_size_of(cipher_name), 1),
+ FEEDBACK_SIZE(fback_bits ? fback_bits / 8: BLOCK_SIZE)
+ {
+ check_feedback(BLOCK_SIZE, FEEDBACK_SIZE, fback_bits, name());
+ }
+
+/*************************************************
+* CFB Encryption Constructor *
+*************************************************/
+CFB_Encryption::CFB_Encryption(const std::string& cipher_name,
+ const SymmetricKey& key,
+ const InitializationVector& iv,
+ u32bit fback_bits) :
+ BlockCipherMode(cipher_name, "CFB", block_size_of(cipher_name), 1),
+ FEEDBACK_SIZE(fback_bits ? fback_bits / 8: BLOCK_SIZE)
+ {
+ check_feedback(BLOCK_SIZE, FEEDBACK_SIZE, fback_bits, name());
+ set_key(key);
+ set_iv(iv);
+ }
+
+/*************************************************
+* Encrypt data in CFB mode *
+*************************************************/
+void CFB_Encryption::write(const byte input[], u32bit length)
+ {
+ while(length)
+ {
+ u32bit xored = std::min(FEEDBACK_SIZE - position, length);
+ xor_buf(buffer + position, input, xored);
+ send(buffer + position, xored);
+ input += xored;
+ length -= xored;
+ position += xored;
+ if(position == FEEDBACK_SIZE)
+ feedback();
+ }
+ }
+
+/*************************************************
+* Do the feedback *
+*************************************************/
+void CFB_Encryption::feedback()
+ {
+ for(u32bit j = 0; j != BLOCK_SIZE - FEEDBACK_SIZE; ++j)
+ state[j] = state[j + FEEDBACK_SIZE];
+ state.copy(BLOCK_SIZE - FEEDBACK_SIZE, buffer, FEEDBACK_SIZE);
+ cipher->encrypt(state, buffer);
+ position = 0;
+ }
+
+/*************************************************
+* CFB Decryption Constructor *
+*************************************************/
+CFB_Decryption::CFB_Decryption(const std::string& cipher_name,
+ u32bit fback_bits) :
+ BlockCipherMode(cipher_name, "CFB", block_size_of(cipher_name), 1),
+ FEEDBACK_SIZE(fback_bits ? fback_bits / 8 : BLOCK_SIZE)
+ {
+ check_feedback(BLOCK_SIZE, FEEDBACK_SIZE, fback_bits, name());
+ }
+
+/*************************************************
+* CFB Decryption Constructor *
+*************************************************/
+CFB_Decryption::CFB_Decryption(const std::string& cipher_name,
+ const SymmetricKey& key,
+ const InitializationVector& iv,
+ u32bit fback_bits) :
+ BlockCipherMode(cipher_name, "CFB", block_size_of(cipher_name), 1),
+ FEEDBACK_SIZE(fback_bits ? fback_bits / 8 : BLOCK_SIZE)
+ {
+ check_feedback(BLOCK_SIZE, FEEDBACK_SIZE, fback_bits, name());
+ set_key(key);
+ set_iv(iv);
+ }
+
+/*************************************************
+* Decrypt data in CFB mode *
+*************************************************/
+void CFB_Decryption::write(const byte input[], u32bit length)
+ {
+ while(length)
+ {
+ u32bit xored = std::min(FEEDBACK_SIZE - position, length);
+ xor_buf(buffer + position, input, xored);
+ send(buffer + position, xored);
+ buffer.copy(position, input, xored);
+ input += xored;
+ length -= xored;
+ position += xored;
+ if(position == FEEDBACK_SIZE)
+ feedback();
+ }
+ }
+
+/*************************************************
+* Do the feedback *
+*************************************************/
+void CFB_Decryption::feedback()
+ {
+ for(u32bit j = 0; j != BLOCK_SIZE - FEEDBACK_SIZE; ++j)
+ state[j] = state[j + FEEDBACK_SIZE];
+ state.copy(BLOCK_SIZE - FEEDBACK_SIZE, buffer, FEEDBACK_SIZE);
+ cipher->encrypt(state, buffer);
+ position = 0;
+ }
+
+}
diff --git a/modules/modes/cfb/cfb.h b/modules/modes/cfb/cfb.h
new file mode 100644
index 000000000..e8133bcf4
--- /dev/null
+++ b/modules/modes/cfb/cfb.h
@@ -0,0 +1,45 @@
+/*************************************************
+* CFB Mode Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_CFB_H__
+#define BOTAN_CFB_H__
+
+#include <botan/modebase.h>
+
+namespace Botan {
+
+/*************************************************
+* CFB Encryption *
+*************************************************/
+class BOTAN_DLL CFB_Encryption : public BlockCipherMode
+ {
+ public:
+ CFB_Encryption(const std::string&, u32bit = 0);
+ CFB_Encryption(const std::string&, const SymmetricKey&,
+ const InitializationVector&, u32bit = 0);
+ private:
+ void write(const byte[], u32bit);
+ void feedback();
+ const u32bit FEEDBACK_SIZE;
+ };
+
+/*************************************************
+* CFB Decryption *
+*************************************************/
+class BOTAN_DLL CFB_Decryption : public BlockCipherMode
+ {
+ public:
+ CFB_Decryption(const std::string&, u32bit = 0);
+ CFB_Decryption(const std::string&, const SymmetricKey&,
+ const InitializationVector&, u32bit = 0);
+ private:
+ void write(const byte[], u32bit);
+ void feedback();
+ const u32bit FEEDBACK_SIZE;
+ };
+
+}
+
+#endif
diff --git a/modules/modes/cfb/modinfo.txt b/modules/modes/cfb/modinfo.txt
new file mode 100644
index 000000000..edce3a7e3
--- /dev/null
+++ b/modules/modes/cfb/modinfo.txt
@@ -0,0 +1,10 @@
+realname "CFB block cipher mode"
+
+define CFB
+
+load_on auto
+
+<add>
+cfb.cpp
+cfb.h
+</add>
diff --git a/modules/modes/ctr/ctr.cpp b/modules/modes/ctr/ctr.cpp
new file mode 100644
index 000000000..8b8c5f35f
--- /dev/null
+++ b/modules/modes/ctr/ctr.cpp
@@ -0,0 +1,74 @@
+/*************************************************
+* CTR Mode Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/ctr.h>
+#include <botan/lookup.h>
+#include <botan/xor_buf.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* CTR-BE Constructor *
+*************************************************/
+CTR_BE::CTR_BE(const std::string& cipher_name) :
+ BlockCipherMode(cipher_name, "CTR-BE", block_size_of(cipher_name), 1)
+ {
+ }
+
+/*************************************************
+* CTR-BE Constructor *
+*************************************************/
+CTR_BE::CTR_BE(const std::string& cipher_name, const SymmetricKey& key,
+ const InitializationVector& iv) :
+ BlockCipherMode(cipher_name, "CTR-BE", block_size_of(cipher_name), 1)
+ {
+ set_key(key);
+ set_iv(iv);
+ }
+
+/*************************************************
+* CTR-BE Encryption/Decryption *
+*************************************************/
+void CTR_BE::write(const byte input[], u32bit length)
+ {
+ u32bit copied = std::min(BLOCK_SIZE - position, length);
+ xor_buf(buffer + position, input, copied);
+ send(buffer + position, copied);
+ input += copied;
+ length -= copied;
+ position += copied;
+
+ if(position == BLOCK_SIZE)
+ increment_counter();
+
+ while(length >= BLOCK_SIZE)
+ {
+ xor_buf(buffer, input, BLOCK_SIZE);
+ send(buffer, BLOCK_SIZE);
+
+ input += BLOCK_SIZE;
+ length -= BLOCK_SIZE;
+ increment_counter();
+ }
+
+ xor_buf(buffer + position, input, length);
+ send(buffer + position, length);
+ position += length;
+ }
+
+/*************************************************
+* Increment the counter and update the buffer *
+*************************************************/
+void CTR_BE::increment_counter()
+ {
+ for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j)
+ if(++state[j])
+ break;
+ cipher->encrypt(state, buffer);
+ position = 0;
+ }
+
+}
diff --git a/modules/modes/ctr/ctr.h b/modules/modes/ctr/ctr.h
new file mode 100644
index 000000000..c3217a5d1
--- /dev/null
+++ b/modules/modes/ctr/ctr.h
@@ -0,0 +1,29 @@
+/*************************************************
+* CTR Mode Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_CTR_H__
+#define BOTAN_CTR_H__
+
+#include <botan/modebase.h>
+
+namespace Botan {
+
+/*************************************************
+* CTR-BE Mode *
+*************************************************/
+class BOTAN_DLL CTR_BE : public BlockCipherMode
+ {
+ public:
+ CTR_BE(const std::string&);
+ CTR_BE(const std::string&,
+ const SymmetricKey&, const InitializationVector&);
+ private:
+ void write(const byte[], u32bit);
+ void increment_counter();
+ };
+
+}
+
+#endif
diff --git a/modules/modes/ctr/modinfo.txt b/modules/modes/ctr/modinfo.txt
new file mode 100644
index 000000000..912b80f51
--- /dev/null
+++ b/modules/modes/ctr/modinfo.txt
@@ -0,0 +1,10 @@
+realname "CTR block cipher mode"
+
+define CTR
+
+load_on auto
+
+<add>
+ctr.cpp
+ctr.h
+</add>
diff --git a/modules/modes/cts/cts.cpp b/modules/modes/cts/cts.cpp
new file mode 100644
index 000000000..8af775713
--- /dev/null
+++ b/modules/modes/cts/cts.cpp
@@ -0,0 +1,175 @@
+/*************************************************
+* CTS Mode Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/cts.h>
+#include <botan/lookup.h>
+#include <botan/xor_buf.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* CTS Encryption Constructor *
+*************************************************/
+CTS_Encryption::CTS_Encryption(const std::string& cipher_name) :
+ BlockCipherMode(cipher_name, "CTS", block_size_of(cipher_name), 0, 2)
+ {
+ }
+
+/*************************************************
+* CTS Encryption Constructor *
+*************************************************/
+CTS_Encryption::CTS_Encryption(const std::string& cipher_name,
+ const SymmetricKey& key,
+ const InitializationVector& iv) :
+ BlockCipherMode(cipher_name, "CTS", block_size_of(cipher_name), 0, 2)
+ {
+ set_key(key);
+ set_iv(iv);
+ }
+
+/*************************************************
+* Encrypt a block *
+*************************************************/
+void CTS_Encryption::encrypt(const byte block[])
+ {
+ xor_buf(state, block, BLOCK_SIZE);
+ cipher->encrypt(state);
+ send(state, BLOCK_SIZE);
+ }
+
+/*************************************************
+* Encrypt in CTS mode *
+*************************************************/
+void CTS_Encryption::write(const byte input[], u32bit length)
+ {
+ u32bit copied = std::min(BUFFER_SIZE - position, length);
+ buffer.copy(position, input, copied);
+ length -= copied;
+ input += copied;
+ position += copied;
+
+ if(length == 0) return;
+
+ encrypt(buffer);
+ if(length > BLOCK_SIZE)
+ {
+ encrypt(buffer + BLOCK_SIZE);
+ while(length > 2*BLOCK_SIZE)
+ {
+ encrypt(input);
+ length -= BLOCK_SIZE;
+ input += BLOCK_SIZE;
+ }
+ position = 0;
+ }
+ else
+ {
+ copy_mem(buffer.begin(), buffer + BLOCK_SIZE, BLOCK_SIZE);
+ position = BLOCK_SIZE;
+ }
+ buffer.copy(position, input, length);
+ position += length;
+ }
+
+/*************************************************
+* Finish encrypting in CTS mode *
+*************************************************/
+void CTS_Encryption::end_msg()
+ {
+ if(position < BLOCK_SIZE + 1)
+ throw Exception("CTS_Encryption: insufficient data to encrypt");
+ xor_buf(state, buffer, BLOCK_SIZE);
+ cipher->encrypt(state);
+ SecureVector<byte> cn = state;
+ clear_mem(buffer + position, BUFFER_SIZE - position);
+ encrypt(buffer + BLOCK_SIZE);
+ send(cn, position - BLOCK_SIZE);
+ }
+
+/*************************************************
+* CTS Decryption Constructor *
+*************************************************/
+CTS_Decryption::CTS_Decryption(const std::string& cipher_name) :
+ BlockCipherMode(cipher_name, "CTS", block_size_of(cipher_name), 0, 2)
+ {
+ temp.create(BLOCK_SIZE);
+ }
+
+/*************************************************
+* CTS Decryption Constructor *
+*************************************************/
+CTS_Decryption::CTS_Decryption(const std::string& cipher_name,
+ const SymmetricKey& key,
+ const InitializationVector& iv) :
+ BlockCipherMode(cipher_name, "CTS", block_size_of(cipher_name), 0, 2)
+ {
+ temp.create(BLOCK_SIZE);
+ set_key(key);
+ set_iv(iv);
+ }
+
+/*************************************************
+* Decrypt a block *
+*************************************************/
+void CTS_Decryption::decrypt(const byte block[])
+ {
+ cipher->decrypt(block, temp);
+ xor_buf(temp, state, BLOCK_SIZE);
+ send(temp, BLOCK_SIZE);
+ state.copy(block, BLOCK_SIZE);
+ }
+
+/*************************************************
+* Decrypt in CTS mode *
+*************************************************/
+void CTS_Decryption::write(const byte input[], u32bit length)
+ {
+ u32bit copied = std::min(BUFFER_SIZE - position, length);
+ buffer.copy(position, input, copied);
+ length -= copied;
+ input += copied;
+ position += copied;
+
+ if(length == 0) return;
+
+ decrypt(buffer);
+ if(length > BLOCK_SIZE)
+ {
+ decrypt(buffer + BLOCK_SIZE);
+ while(length > 2*BLOCK_SIZE)
+ {
+ decrypt(input);
+ length -= BLOCK_SIZE;
+ input += BLOCK_SIZE;
+ }
+ position = 0;
+ }
+ else
+ {
+ copy_mem(buffer.begin(), buffer + BLOCK_SIZE, BLOCK_SIZE);
+ position = BLOCK_SIZE;
+ }
+ buffer.copy(position, input, length);
+ position += length;
+ }
+
+/*************************************************
+* Finish decrypting in CTS mode *
+*************************************************/
+void CTS_Decryption::end_msg()
+ {
+ cipher->decrypt(buffer, temp);
+ xor_buf(temp, buffer + BLOCK_SIZE, position - BLOCK_SIZE);
+ SecureVector<byte> xn = temp;
+ copy_mem(buffer + position, xn + (position - BLOCK_SIZE),
+ BUFFER_SIZE - position);
+ cipher->decrypt(buffer + BLOCK_SIZE, temp);
+ xor_buf(temp, state, BLOCK_SIZE);
+ send(temp, BLOCK_SIZE);
+ send(xn, position - BLOCK_SIZE);
+ }
+
+}
diff --git a/modules/modes/cts/cts.h b/modules/modes/cts/cts.h
new file mode 100644
index 000000000..6a07c4eb2
--- /dev/null
+++ b/modules/modes/cts/cts.h
@@ -0,0 +1,46 @@
+/*************************************************
+* CTS Mode Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_CTS_H__
+#define BOTAN_CTS_H__
+
+#include <botan/modebase.h>
+
+namespace Botan {
+
+/*************************************************
+* CTS Encryption *
+*************************************************/
+class BOTAN_DLL CTS_Encryption : public BlockCipherMode
+ {
+ public:
+ CTS_Encryption(const std::string&);
+ CTS_Encryption(const std::string&,
+ const SymmetricKey&, const InitializationVector&);
+ private:
+ void write(const byte[], u32bit);
+ void end_msg();
+ void encrypt(const byte[]);
+ };
+
+/*************************************************
+* CTS Decryption *
+*************************************************/
+class BOTAN_DLL CTS_Decryption : public BlockCipherMode
+ {
+ public:
+ CTS_Decryption(const std::string&);
+ CTS_Decryption(const std::string&,
+ const SymmetricKey&, const InitializationVector&);
+ private:
+ void write(const byte[], u32bit);
+ void end_msg();
+ void decrypt(const byte[]);
+ SecureVector<byte> temp;
+ };
+
+}
+
+#endif
diff --git a/modules/modes/cts/modinfo.txt b/modules/modes/cts/modinfo.txt
new file mode 100644
index 000000000..9f36221b4
--- /dev/null
+++ b/modules/modes/cts/modinfo.txt
@@ -0,0 +1,10 @@
+realname "CTS block cipher mode"
+
+define CTS
+
+load_on auto
+
+<add>
+cts.cpp
+cts.h
+</add>
diff --git a/modules/modes/eax/eax.cpp b/modules/modes/eax/eax.cpp
new file mode 100644
index 000000000..f246a9dea
--- /dev/null
+++ b/modules/modes/eax/eax.cpp
@@ -0,0 +1,194 @@
+/*************************************************
+* EAX Mode Encryption Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/eax.h>
+#include <botan/lookup.h>
+#include <botan/xor_buf.h>
+#include <botan/parsing.h>
+#include <algorithm>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* EAX MAC-based PRF *
+*************************************************/
+SecureVector<byte> eax_prf(byte tag, u32bit BLOCK_SIZE,
+ MessageAuthenticationCode* mac,
+ const byte in[], u32bit length)
+ {
+ for(u32bit j = 0; j != BLOCK_SIZE - 1; ++j)
+ mac->update(0);
+ mac->update(tag);
+ mac->update(in, length);
+ return mac->final();
+ }
+
+}
+
+/*************************************************
+* EAX_Base Constructor *
+*************************************************/
+EAX_Base::EAX_Base(const std::string& cipher_name,
+ u32bit tag_size) :
+ TAG_SIZE(tag_size ? tag_size / 8 : block_size_of(cipher_name)),
+ BLOCK_SIZE(block_size_of(cipher_name))
+ {
+ const std::string mac_name = "CMAC(" + cipher_name + ")";
+
+ cipher = get_block_cipher(cipher_name);
+ mac = get_mac(mac_name);
+
+ if(tag_size % 8 != 0 || TAG_SIZE == 0 || TAG_SIZE > mac->OUTPUT_LENGTH)
+ throw Invalid_Argument(name() + ": Bad tag size " + to_string(tag_size));
+
+ state.create(BLOCK_SIZE);
+ buffer.create(BLOCK_SIZE);
+ position = 0;
+ }
+
+/*************************************************
+* Check if a keylength is valid for EAX *
+*************************************************/
+bool EAX_Base::valid_keylength(u32bit n) const
+ {
+ if(!cipher->valid_keylength(n))
+ return false;
+ if(!mac->valid_keylength(n))
+ return false;
+ return true;
+ }
+
+/*************************************************
+* Set the EAX key *
+*************************************************/
+void EAX_Base::set_key(const SymmetricKey& key)
+ {
+ cipher->set_key(key);
+ mac->set_key(key);
+ header_mac = eax_prf(1, BLOCK_SIZE, mac, 0, 0);
+ }
+
+/*************************************************
+* Do setup at the start of each message *
+*************************************************/
+void EAX_Base::start_msg()
+ {
+ for(u32bit j = 0; j != BLOCK_SIZE - 1; ++j)
+ mac->update(0);
+ mac->update(2);
+ }
+
+/*************************************************
+* Set the EAX nonce *
+*************************************************/
+void EAX_Base::set_iv(const InitializationVector& iv)
+ {
+ nonce_mac = eax_prf(0, BLOCK_SIZE, mac, iv.begin(), iv.length());
+ state = nonce_mac;
+ cipher->encrypt(state, buffer);
+ }
+
+/*************************************************
+* Set the EAX header *
+*************************************************/
+void EAX_Base::set_header(const byte header[], u32bit length)
+ {
+ header_mac = eax_prf(1, BLOCK_SIZE, mac, header, length);
+ }
+
+/*************************************************
+* Return the name of this cipher mode *
+*************************************************/
+std::string EAX_Base::name() const
+ {
+ return (cipher->name() + "/EAX");
+ }
+
+/*************************************************
+* Increment the counter and update the buffer *
+*************************************************/
+void EAX_Base::increment_counter()
+ {
+ for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j)
+ if(++state[j])
+ break;
+ cipher->encrypt(state, buffer);
+ position = 0;
+ }
+
+/*************************************************
+* EAX_Encryption Constructor *
+*************************************************/
+EAX_Encryption::EAX_Encryption(const std::string& cipher_name,
+ u32bit tag_size) :
+ EAX_Base(cipher_name, tag_size)
+ {
+ }
+
+/*************************************************
+* EAX_Encryption Constructor *
+*************************************************/
+EAX_Encryption::EAX_Encryption(const std::string& cipher_name,
+ const SymmetricKey& key,
+ const InitializationVector& iv,
+ u32bit tag_size) :
+ EAX_Base(cipher_name, tag_size)
+ {
+ set_key(key);
+ set_iv(iv);
+ }
+
+/*************************************************
+* Encrypt in EAX mode *
+*************************************************/
+void EAX_Encryption::write(const byte input[], u32bit length)
+ {
+ u32bit copied = std::min(BLOCK_SIZE - position, length);
+ xor_buf(buffer + position, input, copied);
+ send(buffer + position, copied);
+ mac->update(buffer + position, copied);
+ input += copied;
+ length -= copied;
+ position += copied;
+
+ if(position == BLOCK_SIZE)
+ increment_counter();
+
+ while(length >= BLOCK_SIZE)
+ {
+ xor_buf(buffer, input, BLOCK_SIZE);
+ send(buffer, BLOCK_SIZE);
+ mac->update(buffer, BLOCK_SIZE);
+
+ input += BLOCK_SIZE;
+ length -= BLOCK_SIZE;
+ increment_counter();
+ }
+
+ xor_buf(buffer + position, input, length);
+ send(buffer + position, length);
+ mac->update(buffer + position, length);
+ position += length;
+ }
+
+/*************************************************
+* Finish encrypting in EAX mode *
+*************************************************/
+void EAX_Encryption::end_msg()
+ {
+ SecureVector<byte> data_mac = mac->final();
+ xor_buf(data_mac, nonce_mac, data_mac.size());
+ xor_buf(data_mac, header_mac, data_mac.size());
+
+ send(data_mac, TAG_SIZE);
+
+ state.clear();
+ buffer.clear();
+ position = 0;
+ }
+
+}
diff --git a/modules/modes/eax/eax.h b/modules/modes/eax/eax.h
new file mode 100644
index 000000000..676e5334e
--- /dev/null
+++ b/modules/modes/eax/eax.h
@@ -0,0 +1,72 @@
+/*************************************************
+* EAX Mode Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_EAX_H__
+#define BOTAN_EAX_H__
+
+#include <botan/basefilt.h>
+
+namespace Botan {
+
+/*************************************************
+* EAX Base Class *
+*************************************************/
+class BOTAN_DLL EAX_Base : public Keyed_Filter
+ {
+ public:
+ void set_key(const SymmetricKey&);
+ void set_iv(const InitializationVector&);
+ void set_header(const byte[], u32bit);
+ std::string name() const;
+
+ bool valid_keylength(u32bit) const;
+
+ ~EAX_Base() { delete cipher; delete mac; }
+ protected:
+ EAX_Base(const std::string&, u32bit);
+ void start_msg();
+ void increment_counter();
+
+ const u32bit TAG_SIZE, BLOCK_SIZE;
+ BlockCipher* cipher;
+ MessageAuthenticationCode* mac;
+ SecureVector<byte> nonce_mac, header_mac, state, buffer;
+ u32bit position;
+ };
+
+/*************************************************
+* EAX Encryption *
+*************************************************/
+class BOTAN_DLL EAX_Encryption : public EAX_Base
+ {
+ public:
+ EAX_Encryption(const std::string&, u32bit = 0);
+ EAX_Encryption(const std::string&, const SymmetricKey&,
+ const InitializationVector&, u32bit = 0);
+ private:
+ void write(const byte[], u32bit);
+ void end_msg();
+ };
+
+/*************************************************
+* EAX Decryption *
+*************************************************/
+class BOTAN_DLL EAX_Decryption : public EAX_Base
+ {
+ public:
+ EAX_Decryption(const std::string&, u32bit = 0);
+ EAX_Decryption(const std::string&, const SymmetricKey&,
+ const InitializationVector&, u32bit = 0);
+ private:
+ void write(const byte[], u32bit);
+ void do_write(const byte[], u32bit);
+ void end_msg();
+ SecureVector<byte> queue;
+ u32bit queue_start, queue_end;
+ };
+
+}
+
+#endif
diff --git a/modules/modes/eax/eax_dec.cpp b/modules/modes/eax/eax_dec.cpp
new file mode 100644
index 000000000..70cdd9863
--- /dev/null
+++ b/modules/modes/eax/eax_dec.cpp
@@ -0,0 +1,126 @@
+/*************************************************
+* EAX Mode Encryption Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/eax.h>
+#include <botan/lookup.h>
+#include <botan/xor_buf.h>
+#include <botan/parsing.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* EAX_Decryption Constructor *
+*************************************************/
+EAX_Decryption::EAX_Decryption(const std::string& cipher_name,
+ u32bit tag_size) :
+ EAX_Base(cipher_name, tag_size)
+ {
+ queue.create(2*TAG_SIZE + DEFAULT_BUFFERSIZE);
+ queue_start = queue_end = 0;
+ }
+
+/*************************************************
+* EAX_Decryption Constructor *
+*************************************************/
+EAX_Decryption::EAX_Decryption(const std::string& cipher_name,
+ const SymmetricKey& key,
+ const InitializationVector& iv,
+ u32bit tag_size) :
+ EAX_Base(cipher_name, tag_size)
+ {
+ set_key(key);
+ set_iv(iv);
+ queue.create(2*TAG_SIZE + DEFAULT_BUFFERSIZE);
+ queue_start = queue_end = 0;
+ }
+
+/*************************************************
+* Decrypt in EAX mode *
+*************************************************/
+void EAX_Decryption::write(const byte input[], u32bit length)
+ {
+ while(length)
+ {
+ const u32bit copied = std::min(length, queue.size() - queue_end);
+
+ queue.copy(queue_end, input, copied);
+ input += copied;
+ length -= copied;
+ queue_end += copied;
+
+ SecureVector<byte> block_buf(cipher->BLOCK_SIZE);
+ while((queue_end - queue_start) > TAG_SIZE)
+ {
+ u32bit removed = (queue_end - queue_start) - TAG_SIZE;
+ do_write(queue + queue_start, removed);
+ queue_start += removed;
+ }
+
+ if(queue_start + TAG_SIZE == queue_end &&
+ queue_start >= queue.size() / 2)
+ {
+ SecureVector<byte> queue_data(TAG_SIZE);
+ queue_data.copy(queue + queue_start, TAG_SIZE);
+ queue.copy(queue_data, TAG_SIZE);
+ queue_start = 0;
+ queue_end = TAG_SIZE;
+ }
+ }
+ }
+
+/*************************************************
+* Decrypt in EAX mode *
+*************************************************/
+void EAX_Decryption::do_write(const byte input[], u32bit length)
+ {
+ mac->update(input, length);
+
+ u32bit copied = std::min(BLOCK_SIZE - position, length);
+ xor_buf(buffer + position, input, copied);
+ send(buffer + position, copied);
+ input += copied;
+ length -= copied;
+ position += copied;
+
+ if(position == BLOCK_SIZE)
+ increment_counter();
+
+ while(length >= BLOCK_SIZE)
+ {
+ xor_buf(buffer, input, BLOCK_SIZE);
+ send(buffer, BLOCK_SIZE);
+
+ input += BLOCK_SIZE;
+ length -= BLOCK_SIZE;
+ increment_counter();
+ }
+
+ xor_buf(buffer + position, input, length);
+ send(buffer + position, length);
+ position += length;
+ }
+
+/*************************************************
+* Finish decrypting in EAX mode *
+*************************************************/
+void EAX_Decryption::end_msg()
+ {
+ if((queue_end - queue_start) != TAG_SIZE)
+ throw Integrity_Failure(name() + ": Message authentication failure");
+
+ SecureVector<byte> data_mac = mac->final();
+
+ for(u32bit j = 0; j != TAG_SIZE; ++j)
+ if(queue[queue_start+j] != (data_mac[j] ^ nonce_mac[j] ^ header_mac[j]))
+ throw Integrity_Failure(name() + ": Message authentication failure");
+
+ state.clear();
+ buffer.clear();
+ position = 0;
+ queue_start = queue_end = 0;
+ }
+
+}
diff --git a/modules/modes/eax/modinfo.txt b/modules/modes/eax/modinfo.txt
new file mode 100644
index 000000000..7d5f7e98c
--- /dev/null
+++ b/modules/modes/eax/modinfo.txt
@@ -0,0 +1,11 @@
+realname "EAX block cipher mode"
+
+define EAX
+
+load_on auto
+
+<add>
+eax.cpp
+eax.h
+eax_dec.cpp
+</add>
diff --git a/modules/modes/ecb/ecb.cpp b/modules/modes/ecb/ecb.cpp
new file mode 100644
index 000000000..8effac1d5
--- /dev/null
+++ b/modules/modes/ecb/ecb.cpp
@@ -0,0 +1,152 @@
+/*************************************************
+* ECB Mode Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/ecb.h>
+#include <botan/lookup.h>
+
+namespace Botan {
+
+/*************************************************
+* ECB Constructor *
+*************************************************/
+ECB::ECB(const std::string& cipher_name, const std::string& padding_name) :
+ BlockCipherMode(cipher_name, "ECB", 0), padder(get_bc_pad(padding_name))
+ {
+ }
+
+/*************************************************
+* Verify the IV is not set *
+*************************************************/
+bool ECB::valid_iv_size(u32bit iv_size) const
+ {
+ if(iv_size == 0)
+ return true;
+ return false;
+ }
+
+/*************************************************
+* Return an ECB mode name *
+*************************************************/
+std::string ECB::name() const
+ {
+ return (cipher->name() + "/" + mode_name + "/" + padder->name());
+ }
+
+/*************************************************
+* ECB Encryption Constructor *
+*************************************************/
+ECB_Encryption::ECB_Encryption(const std::string& cipher_name,
+ const std::string& padding_name) :
+ ECB(cipher_name, padding_name)
+ {
+ }
+
+/*************************************************
+* ECB Encryption Constructor *
+*************************************************/
+ECB_Encryption::ECB_Encryption(const std::string& cipher_name,
+ const std::string& padding_name,
+ const SymmetricKey& key) :
+ ECB(cipher_name, padding_name)
+ {
+ set_key(key);
+ }
+
+/*************************************************
+* Encrypt in ECB mode *
+*************************************************/
+void ECB_Encryption::write(const byte input[], u32bit length)
+ {
+ buffer.copy(position, input, length);
+ if(position + length >= BLOCK_SIZE)
+ {
+ cipher->encrypt(buffer);
+ send(buffer, BLOCK_SIZE);
+ input += (BLOCK_SIZE - position);
+ length -= (BLOCK_SIZE - position);
+ while(length >= BLOCK_SIZE)
+ {
+ cipher->encrypt(input, buffer);
+ send(buffer, BLOCK_SIZE);
+ input += BLOCK_SIZE;
+ length -= BLOCK_SIZE;
+ }
+ buffer.copy(input, length);
+ position = 0;
+ }
+ position += length;
+ }
+
+/*************************************************
+* Finish encrypting in ECB mode *
+*************************************************/
+void ECB_Encryption::end_msg()
+ {
+ SecureVector<byte> padding(BLOCK_SIZE);
+ padder->pad(padding, padding.size(), position);
+ write(padding, padder->pad_bytes(BLOCK_SIZE, position));
+ if(position != 0)
+ throw Encoding_Error(name() + ": Did not pad to full blocksize");
+ }
+
+/*************************************************
+* ECB Decryption Constructor *
+*************************************************/
+ECB_Decryption::ECB_Decryption(const std::string& cipher_name,
+ const std::string& padding_name) :
+ ECB(cipher_name, padding_name)
+ {
+ }
+
+/*************************************************
+* ECB Decryption Constructor *
+*************************************************/
+ECB_Decryption::ECB_Decryption(const std::string& cipher_name,
+ const std::string& padding_name,
+ const SymmetricKey& key) :
+ ECB(cipher_name, padding_name)
+ {
+ set_key(key);
+ }
+
+/*************************************************
+* Decrypt in ECB mode *
+*************************************************/
+void ECB_Decryption::write(const byte input[], u32bit length)
+ {
+ buffer.copy(position, input, length);
+ if(position + length > BLOCK_SIZE)
+ {
+ cipher->decrypt(buffer);
+ send(buffer, BLOCK_SIZE);
+ input += (BLOCK_SIZE - position);
+ length -= (BLOCK_SIZE - position);
+ while(length > BLOCK_SIZE)
+ {
+ cipher->decrypt(input, buffer);
+ send(buffer, BLOCK_SIZE);
+ input += BLOCK_SIZE;
+ length -= BLOCK_SIZE;
+ }
+ buffer.copy(input, length);
+ position = 0;
+ }
+ position += length;
+ }
+
+/*************************************************
+* Finish decrypting in ECB mode *
+*************************************************/
+void ECB_Decryption::end_msg()
+ {
+ if(position != BLOCK_SIZE)
+ throw Decoding_Error(name());
+ cipher->decrypt(buffer);
+ send(buffer, padder->unpad(buffer, BLOCK_SIZE));
+ state = buffer;
+ position = 0;
+ }
+
+}
diff --git a/modules/modes/ecb/ecb.h b/modules/modes/ecb/ecb.h
new file mode 100644
index 000000000..b730a4fd4
--- /dev/null
+++ b/modules/modes/ecb/ecb.h
@@ -0,0 +1,57 @@
+/*************************************************
+* ECB Mode Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_ECB_H__
+#define BOTAN_ECB_H__
+
+#include <botan/modebase.h>
+#include <botan/mode_pad.h>
+
+namespace Botan {
+
+/*************************************************
+* ECB *
+*************************************************/
+class BOTAN_DLL ECB : public BlockCipherMode
+ {
+ protected:
+ ECB(const std::string&, const std::string&);
+ std::string name() const;
+ const BlockCipherModePaddingMethod* padder;
+ private:
+ bool valid_iv_size(u32bit) const;
+ };
+
+/*************************************************
+* ECB Encryption *
+*************************************************/
+class BOTAN_DLL ECB_Encryption : public ECB
+ {
+ public:
+ ECB_Encryption(const std::string&, const std::string&);
+ ECB_Encryption(const std::string&, const std::string&,
+ const SymmetricKey&);
+ private:
+ void write(const byte[], u32bit);
+ void end_msg();
+ };
+
+/*************************************************
+* ECB Decryption *
+*************************************************/
+class BOTAN_DLL ECB_Decryption : public ECB
+ {
+ public:
+ ECB_Decryption(const std::string&, const std::string&);
+ ECB_Decryption(const std::string&, const std::string&,
+ const SymmetricKey&);
+ private:
+ void write(const byte[], u32bit);
+ void end_msg();
+ };
+
+}
+
+#endif
diff --git a/modules/modes/ecb/modinfo.txt b/modules/modes/ecb/modinfo.txt
new file mode 100644
index 000000000..fb0c8b7c6
--- /dev/null
+++ b/modules/modes/ecb/modinfo.txt
@@ -0,0 +1,10 @@
+realname "ECB block cipher mode"
+
+define ECB
+
+load_on auto
+
+<add>
+ecb.cpp
+ecb.h
+</add>
diff --git a/modules/modes/ofb/modinfo.txt b/modules/modes/ofb/modinfo.txt
new file mode 100644
index 000000000..38a15d0b6
--- /dev/null
+++ b/modules/modes/ofb/modinfo.txt
@@ -0,0 +1,10 @@
+realname "OFB block cipher mode"
+
+define OFB
+
+load_on auto
+
+<add>
+ofb.cpp
+ofb.h
+</add>
diff --git a/modules/modes/ofb/ofb.cpp b/modules/modes/ofb/ofb.cpp
new file mode 100644
index 000000000..db254d329
--- /dev/null
+++ b/modules/modes/ofb/ofb.cpp
@@ -0,0 +1,65 @@
+/*************************************************
+* OFB Mode Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/ofb.h>
+#include <botan/lookup.h>
+#include <botan/xor_buf.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* OFB Constructor *
+*************************************************/
+OFB::OFB(const std::string& cipher_name) :
+ BlockCipherMode(cipher_name, "OFB", block_size_of(cipher_name), 2)
+ {
+ }
+
+/*************************************************
+* OFB Constructor *
+*************************************************/
+OFB::OFB(const std::string& cipher_name, const SymmetricKey& key,
+ const InitializationVector& iv) :
+ BlockCipherMode(cipher_name, "OFB", block_size_of(cipher_name), 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/modules/modes/ofb/ofb.h b/modules/modes/ofb/ofb.h
new file mode 100644
index 000000000..3bf6f9883
--- /dev/null
+++ b/modules/modes/ofb/ofb.h
@@ -0,0 +1,28 @@
+/*************************************************
+* OFB Mode Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_OFB_H__
+#define BOTAN_OFB_H__
+
+#include <botan/modebase.h>
+
+namespace Botan {
+
+/*************************************************
+* OFB Mode *
+*************************************************/
+class BOTAN_DLL OFB : public BlockCipherMode
+ {
+ public:
+ OFB(const std::string&);
+ OFB(const std::string&,
+ const SymmetricKey&, const InitializationVector&);
+ private:
+ void write(const byte[], u32bit);
+ };
+
+}
+
+#endif