diff options
-rw-r--r-- | checks/bench.cpp | 7 | ||||
-rw-r--r-- | checks/validate.dat | 46 | ||||
-rw-r--r-- | doc/log.txt | 1 | ||||
-rw-r--r-- | src/block/cascade/cascade.cpp | 98 | ||||
-rw-r--r-- | src/block/cascade/cascade.h | 41 | ||||
-rw-r--r-- | src/block/cascade/info.txt | 9 | ||||
-rw-r--r-- | src/engine/def_engine/lookup_block.cpp | 15 |
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)) { |