aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-01-11 22:07:34 +0000
committerlloyd <[email protected]>2010-01-11 22:07:34 +0000
commitf5fd85b0ea6a5a6975d595130e029f94fddae9a4 (patch)
tree3e1de8daf0e513096a8a98f6a087015e85081340 /src
parent3c3ca9050f2ffbb9bb3417e2d71142e9550936df (diff)
Add block cipher cascade
Diffstat (limited to 'src')
-rw-r--r--src/block/cascade/cascade.cpp98
-rw-r--r--src/block/cascade/cascade.h41
-rw-r--r--src/block/cascade/info.txt9
-rw-r--r--src/engine/def_engine/lookup_block.cpp15
4 files changed, 163 insertions, 0 deletions
diff --git a/src/block/cascade/cascade.cpp b/src/block/cascade/cascade.cpp
new file mode 100644
index 000000000..f72ef7b76
--- /dev/null
+++ b/src/block/cascade/cascade.cpp
@@ -0,0 +1,98 @@
+/*
+* Block Cipher Cascade
+* (C) 2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/cascade.h>
+
+namespace Botan {
+
+void Cascade_Cipher::encrypt_n(const byte in[], byte out[],
+ u32bit blocks) const
+ {
+ u32bit c1_blocks = blocks * (BLOCK_SIZE / cipher1->BLOCK_SIZE);
+ u32bit c2_blocks = blocks * (BLOCK_SIZE / cipher2->BLOCK_SIZE);
+
+ cipher1->encrypt_n(in, out, c1_blocks);
+ cipher2->encrypt_n(out, out, c2_blocks);
+ }
+
+void Cascade_Cipher::decrypt_n(const byte in[], byte out[],
+ u32bit blocks) const
+ {
+ u32bit c1_blocks = blocks * (BLOCK_SIZE / cipher1->BLOCK_SIZE);
+ u32bit c2_blocks = blocks * (BLOCK_SIZE / cipher2->BLOCK_SIZE);
+
+ cipher2->decrypt_n(in, out, c2_blocks);
+ cipher1->decrypt_n(out, out, c1_blocks);
+ }
+
+void Cascade_Cipher::key_schedule(const byte key[], u32bit)
+ {
+ const byte* key2 = key + cipher1->MAXIMUM_KEYLENGTH;
+
+ cipher1->set_key(key , cipher1->MAXIMUM_KEYLENGTH);
+ cipher2->set_key(key2, cipher2->MAXIMUM_KEYLENGTH);
+ }
+
+void Cascade_Cipher::clear()
+ {
+ cipher1->clear();
+ cipher2->clear();
+ }
+
+std::string Cascade_Cipher::name() const
+ {
+ return "Cascade(" + cipher1->name() + "," + cipher2->name() + ")";
+ }
+
+BlockCipher* Cascade_Cipher::clone() const
+ {
+ return new Cascade_Cipher(cipher1->clone(),
+ cipher2->clone());
+ }
+
+namespace {
+
+u32bit euclids_algorithm(u32bit a, u32bit b)
+ {
+ while(b != 0) // gcd
+ {
+ u32bit t = b;
+ b = a % b;
+ a = t;
+ }
+
+ return a;
+ }
+
+u32bit block_size_for_cascade(u32bit bs, u32bit bs2)
+ {
+ if(bs == bs2)
+ return bs;
+
+ u32bit gcd = euclids_algorithm(bs, bs2);
+
+ return (bs * bs2) / gcd;
+ }
+
+}
+
+Cascade_Cipher::Cascade_Cipher(BlockCipher* c1, BlockCipher* c2) :
+ BlockCipher(block_size_for_cascade(c1->BLOCK_SIZE, c2->BLOCK_SIZE),
+ c1->MAXIMUM_KEYLENGTH + c2->MAXIMUM_KEYLENGTH),
+ cipher1(c1), cipher2(c2)
+ {
+ if(BLOCK_SIZE % c1->BLOCK_SIZE || BLOCK_SIZE % c2->BLOCK_SIZE)
+ throw Internal_Error("Failure in " + name() + " constructor");
+ }
+
+Cascade_Cipher::~Cascade_Cipher()
+ {
+ delete cipher1;
+ delete cipher2;
+ }
+
+}
diff --git a/src/block/cascade/cascade.h b/src/block/cascade/cascade.h
new file mode 100644
index 000000000..98c64fb3e
--- /dev/null
+++ b/src/block/cascade/cascade.h
@@ -0,0 +1,41 @@
+/*
+* Block Cipher Cascade
+* (C) 2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_CASCADE_H__
+#define BOTAN_CASCADE_H__
+
+#include <botan/block_cipher.h>
+
+namespace Botan {
+
+/*
+* Block Cipher Cascade
+*/
+class BOTAN_DLL Cascade_Cipher : public BlockCipher
+ {
+ public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ void clear();
+ std::string name() const;
+ BlockCipher* clone() const;
+
+ Cascade_Cipher(BlockCipher* cipher1, BlockCipher* cipher2);
+
+ ~Cascade_Cipher();
+ private:
+ void key_schedule(const byte[], u32bit);
+
+ BlockCipher* cipher1;
+ BlockCipher* cipher2;
+ };
+
+
+}
+
+#endif
diff --git a/src/block/cascade/info.txt b/src/block/cascade/info.txt
new file mode 100644
index 000000000..0e6f4acdd
--- /dev/null
+++ b/src/block/cascade/info.txt
@@ -0,0 +1,9 @@
+define CASCADE
+
+<header:public>
+cascade.h
+</header:public>
+
+<source>
+cascade.cpp
+</source>
diff --git a/src/engine/def_engine/lookup_block.cpp b/src/engine/def_engine/lookup_block.cpp
index cdad76c46..097a471b7 100644
--- a/src/engine/def_engine/lookup_block.cpp
+++ b/src/engine/def_engine/lookup_block.cpp
@@ -22,6 +22,10 @@
#include <botan/cast256.h>
#endif
+#if defined(BOTAN_HAS_CASCADE)
+ #include <botan/cascade.h>
+#endif
+
#if defined(BOTAN_HAS_DES)
#include <botan/des.h>
#include <botan/desx.h>
@@ -240,6 +244,17 @@ Default_Engine::find_block_cipher(const SCAN_Name& request,
}
#endif
+#if defined(BOTAN_HAS_CASCADE)
+ if(request.algo_name() == "Cascade" && request.arg_count() == 2)
+ {
+ const BlockCipher* c1 = af.prototype_block_cipher(request.arg(0));
+ const BlockCipher* c2 = af.prototype_block_cipher(request.arg(1));
+
+ if(c1 && c2)
+ return new Cascade_Cipher(c1->clone(), c2->clone());
+ }
+#endif
+
#if defined(BOTAN_HAS_LION)
if(request.algo_name() == "Lion" && request.arg_count_between(2, 3))
{