aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checks/bench.cpp7
-rw-r--r--checks/validate.dat46
-rw-r--r--doc/log.txt1
-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
7 files changed, 215 insertions, 2 deletions
diff --git a/checks/bench.cpp b/checks/bench.cpp
index 7082eca68..cfb44070d 100644
--- a/checks/bench.cpp
+++ b/checks/bench.cpp
@@ -35,8 +35,6 @@ const std::string algos[] = {
"GOST",
"IDEA",
"KASUMI",
- "Lion(SHA-256,Turing,8192)",
- "Luby-Rackoff(SHA-512)",
"MARS",
"MISTY1",
"Noekeon",
@@ -54,6 +52,11 @@ const std::string algos[] = {
"Twofish",
"XTEA",
+ /* Cipher constructions */
+ "Cascade(Serpent,AES-128)",
+ "Lion(SHA-256,Salsa20,8192)",
+ "Luby-Rackoff(SHA-512)",
+
/* Cipher modes */
"TripleDES/CBC/PKCS7",
"TripleDES/CBC/CTS",
diff --git a/checks/validate.dat b/checks/validate.dat
index 9150c6b51..524e652dd 100644
--- a/checks/validate.dat
+++ b/checks/validate.dat
@@ -22950,6 +22950,52 @@ F922CA875B991A31:2763F255636A34C1:22EBE7A30E8855B3B453A6E926D4F187
B4ECC305C3DBD8E5:FBBEC8F5DBF4CEFD:1B5E23EBD915C1FEE59F57DD91AF7347
3DAADD7A9633E19B:4DE5C07EA1564A64:A6BFB85FA91B8CA4197C8B502A62F972
+# Cascade tests generated by Crypto++ 5.6.0
+[Cascade(Serpent,Twofish)]
+0000000000000000000000000000000000000000000000000000000000000000:\
+E78516D21D23DA501939C24C48BCC79DE78516D21D23DA501939C24C48BCC79D:\
+B50638F695AFA16F9378D43374CA8568600135ECD1E513838722366346BC4B21\
+01422291558FAA30A3196CBEB42E67F4C075882482897F72A8A30AE9B3AD426D
+
+47CB8147C5290D6F94FBF3351777087FA731610A3F66E3CCFA6D9B18F980E687:\
+F234E056923B3DB26AABC8F604F0CE2C1A7F4C35B0B74958014D791668FF6BF4:\
+9E8F6BC09768AED8F533FA4FC35FF6FEB8020FFBC8350DDFD20ACA7ECF1889CF\
+BFCD78E261B9A3CD825401AFA7ADCDFA88DBA8230FB92D4B942C25EE92F27A02
+
+B9A28D32734EF678BACD5539FF9FF951AF81F44AFE223256E5D8898FB862A767\
+B90BD2D95E17E4411D02D49481CCE4191EE2C7AE8EBDF6312BDC66317AD42140:\
+065E390C4FD10E9929F30D89A67E0D4CFA3AF90BEF46B2B435B53CBE0B7DD1B6\
+12D4C5E2D03028B488000C06517434FC70F7B62C273CA5DEBD9CA7034D853087:\
+1EF34E47005028F2D95120052855C6001225200A333CA4D7D5A356B5554EE2AE\
+7EBC9BA57BADA0DAFC84C2187C51CB3CCB5EEE40F27C00537FFFCA2851DD8BD8
+
+[Cascade(Serpent,AES-256)]
+06CEB2B4FD2F0A27B3C90D77D2E9BBD3665A8DCAC9187B1EE9F6A60D39042A9D\
+3719883B3E87845B9D4A8BE258379959775969CBF5768A359797B2FA19FC2FCC:\
+05FFBF6E8097FC746FFAD8C3306E6DB668148796180F26CA5DE06AE76DE16D07\
+8A0E72B259982423ED96FF95719DEB160CEFE7697752B0CFA984A18DDCEF2EC0:\
+EE426051D1ADCE09AC02E2023331F273BB1B2C4C5905DEDA3E1032CCD0DB5611\
+5B011F05688F781E3F790364968E06DC6E7BD5FA38DB068CBD34A85B6B3A9458
+
+FBAF0DE6C09D10EB31F21A7C784BF453F82F51EFFA8B363EE6B33DF15204F434\
+45170DED1E39AB922548ED82AAADED6BF470A5226B69D025FE3D532AADDA069C\
+464D2C8A65E1A18698BD521AFB3053229C1539626392031F8C36229FF3178A7F\
+5C716E30DBEFDDD4AC2113071977B795A8B29DA7F467471A996FB63136387C28:\
+7ED1F730EED52DFB63E073A40EAE404E443ACEB9A3B55132E740ACE1EEDF99D0\
+F22B3F2326E2E124594E75ED1915C8D155F24269254B22B6E8C53E9F64E70552\
+D5E3004782C6C47341EBF8716B59DAB49B512B6DF7F9D7FB914FFA56F7F89B56\
+1B6A5DFE9334B7561144B25FE0F57BEBB4058EC7D9EEA57AB62825A86312BBC3:\
+CDCD23F5518DB5DAE8C69B56EB352D4F3C4A64A5FFC8E5BC2511B8310993C48E\
+FA30A0F9E2B98A0FB1FE64173E6A8038047AEBAE22E17392FE32CF1D0DE3BB76
+
+[Cascade(Serpent,CAST-128)]
+27EDE4B2A3784A33898FA330167317BF7354072672D49DD03D13D3F0856CF3D9\
+C17C1237565E7320BDD23C03BDE195A4FE58623A983DB9C308D5A976D92CD6A2:\
+2D7096A03BAB4DBDABEDB9F069FE68C3E12ED65ACCE43ECF7F6D810B5EEC36A5\
+22B605715BE12003E324436652BEA06BD289DBE886A5DE9E51CFF6C065A21F2B:\
+EFA9CC5F3E245AB463CC60A5015CB0F663676760832CEE6C633A518112E518D4\
+5DD4B627E9507CDB03A1ADD870E28362
+
# MARKER: Cipher Modes
# Cipher mode format is plaintext:ciphertext:key:iv
diff --git a/doc/log.txt b/doc/log.txt
index 60a20a112..c729179b8 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -3,6 +3,7 @@
- Add SSE2 implementation of IDEA
- Perform XTS encryption and decryption in parallel where possible
- Perform CBC decryption in parallel where possible
+ - Add a block cipher cascade construction
- Add support for Win32 high resolution system timers
- Remove Timer class entirely
- Switch default PKCS #8 encryption algorithm from 3DES to AES-256
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))
{