aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-04-24 20:09:51 +0000
committerlloyd <[email protected]>2012-04-24 20:09:51 +0000
commit25f329b8a45b6f84f9a01a0326db48f6853dc59c (patch)
treef9d18d9c03fdfe9832d672eac6b69dd5fd121e66
parent1ffda187674d4ca21f294a4080f52182b5f4a6ed (diff)
Patrick Pelletier noted on the mailing list that the implementation of
Camellia exposed by the OpenSSL module is parameterized by the key length, much as AES is, while the version in the main source uses a single name/type for all variants. For consistency, convert to using a key length parameterized name in our version as well. In the future this might allow for better loop unrolling, etc but currently we don't make use of that.
-rw-r--r--checks/validate.dat22
-rw-r--r--src/block/camellia/camellia.cpp226
-rw-r--r--src/block/camellia/camellia.h44
-rw-r--r--src/engine/core_engine/lookup_block.cpp8
4 files changed, 191 insertions, 109 deletions
diff --git a/checks/validate.dat b/checks/validate.dat
index 6b9a49e52..4c579bf81 100644
--- a/checks/validate.dat
+++ b/checks/validate.dat
@@ -4123,26 +4123,28 @@ F0E1D2C3B4A5968778695A4B3C2D1E0F00112233445566
FEDCBA9876543210:05044B62FA52D080:\
F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344556677
-[Camellia]
+[Camellia-128]
# From RFC 3713
-
0123456789ABCDEFFEDCBA9876543210:67673138549669730857065648EABE43:\
0123456789ABCDEFFEDCBA9876543210
-0123456789ABCDEFFEDCBA9876543210:B4993401B3E996F84EE5CEE7D79B09B9:\
-0123456789ABCDEFFEDCBA98765432100011223344556677
-
-0123456789ABCDEFFEDCBA9876543210:9ACC237DFF16D76C20EF7C919E3A7509:\
-0123456789ABCDEFFEDCBA987654321000112233445566778899AABBCCDDEEFF
-
-# From NESSIE
-
+# Nessie
00000000000000000000000000000000:6C227F749319A3AA7DA235A9BBA05A2C:\
80000000000000000000000000000000
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:25DD9EB9DD67FBC6E8431F56F4FBE651:\
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+[Camellia-192]
+# From RFC 3713
+0123456789ABCDEFFEDCBA9876543210:B4993401B3E996F84EE5CEE7D79B09B9:\
+0123456789ABCDEFFEDCBA98765432100011223344556677
+
+[Camellia-256]
+# From RFC 3713
+0123456789ABCDEFFEDCBA9876543210:9ACC237DFF16D76C20EF7C919E3A7509:\
+0123456789ABCDEFFEDCBA987654321000112233445566778899AABBCCDDEEFF
+
# First one is from RFC 2144. The rest were done with OpenSSL and bits taken
# from /dev/urandom
[CAST-128]
diff --git a/src/block/camellia/camellia.cpp b/src/block/camellia/camellia.cpp
index 54c54e7d2..2b4862efc 100644
--- a/src/block/camellia/camellia.cpp
+++ b/src/block/camellia/camellia.cpp
@@ -103,103 +103,11 @@ u64bit left_rot_lo(u64bit h, u64bit l, size_t shift)
return (h >> (64-shift)) | (l << shift);
}
-}
-
-}
-
-/*
-* Camellia Encryption
-*/
-void Camellia::encrypt_n(const byte in[], byte out[], size_t blocks) const
- {
- using namespace Camellia_F;
-
- for(size_t i = 0; i != blocks; ++i)
- {
- u64bit D1 = load_be<u64bit>(in, 0);
- u64bit D2 = load_be<u64bit>(in, 1);
-
- const u64bit* K = &SK[0];
-
- D1 ^= *K++;
- D2 ^= *K++;
-
- while(true)
- {
- D2 ^= F(D1, *K++);
- D1 ^= F(D2, *K++);
- D2 ^= F(D1, *K++);
- D1 ^= F(D2, *K++);
- D2 ^= F(D1, *K++);
- D1 ^= F(D2, *K++);
-
- if(K == &SK[SK.size()-2])
- break;
-
- D1 = FL (D1, *K++);
- D2 = FLINV(D2, *K++);
- }
-
- D2 ^= *K++;
- D1 ^= *K++;
-
- store_be(out, D2, D1);
-
- in += BLOCK_SIZE;
- out += BLOCK_SIZE;
- }
- }
-
-/*
-* Camellia Decryption
-*/
-void Camellia::decrypt_n(const byte in[], byte out[], size_t blocks) const
- {
- using namespace Camellia_F;
-
- for(size_t i = 0; i != blocks; ++i)
- {
- u64bit D1 = load_be<u64bit>(in, 0);
- u64bit D2 = load_be<u64bit>(in, 1);
-
- const u64bit* K = &SK[SK.size()-1];
-
- D2 ^= *K--;
- D1 ^= *K--;
-
- while(true)
- {
- D2 ^= F(D1, *K--);
- D1 ^= F(D2, *K--);
- D2 ^= F(D1, *K--);
- D1 ^= F(D2, *K--);
- D2 ^= F(D1, *K--);
- D1 ^= F(D2, *K--);
-
- if(K == &SK[1])
- break;
-
- D1 = FL (D1, *K--);
- D2 = FLINV(D2, *K--);
- }
-
- D1 ^= *K--;
- D2 ^= *K;
-
- store_be(out, D2, D1);
-
- in += BLOCK_SIZE;
- out += BLOCK_SIZE;
- }
- }
-
/*
* Camellia Key Schedule
*/
-void Camellia::key_schedule(const byte key[], size_t length)
+void key_schedule(SecureVector<u64bit>& SK, const byte key[], size_t length)
{
- using namespace Camellia_F;
-
const u64bit Sigma1 = 0xA09E667F3BCC908B;
const u64bit Sigma2 = 0xB67AE8584CAA73B2;
const u64bit Sigma3 = 0xC6EF372FE94F82BE;
@@ -312,4 +220,136 @@ void Camellia::key_schedule(const byte key[], size_t length)
}
}
+
+/*
+* Camellia Encryption
+*/
+void encrypt(const byte in[], byte out[], size_t blocks, const SecureVector<u64bit>& SK)
+ {
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ u64bit D1 = load_be<u64bit>(in, 0);
+ u64bit D2 = load_be<u64bit>(in, 1);
+
+ const u64bit* K = &SK[0];
+
+ D1 ^= *K++;
+ D2 ^= *K++;
+
+ while(true)
+ {
+ D2 ^= F(D1, *K++);
+ D1 ^= F(D2, *K++);
+ D2 ^= F(D1, *K++);
+ D1 ^= F(D2, *K++);
+ D2 ^= F(D1, *K++);
+ D1 ^= F(D2, *K++);
+
+ if(K == &SK[SK.size()-2])
+ break;
+
+ D1 = FL (D1, *K++);
+ D2 = FLINV(D2, *K++);
+ }
+
+ D2 ^= *K++;
+ D1 ^= *K++;
+
+ store_be(out, D2, D1);
+
+ in += 16;
+ out += 16;
+ }
+ }
+
+/*
+* Camellia Decryption
+*/
+void decrypt(const byte in[], byte out[], size_t blocks, const SecureVector<u64bit>& SK)
+ {
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ u64bit D1 = load_be<u64bit>(in, 0);
+ u64bit D2 = load_be<u64bit>(in, 1);
+
+ const u64bit* K = &SK[SK.size()-1];
+
+ D2 ^= *K--;
+ D1 ^= *K--;
+
+ while(true)
+ {
+ D2 ^= F(D1, *K--);
+ D1 ^= F(D2, *K--);
+ D2 ^= F(D1, *K--);
+ D1 ^= F(D2, *K--);
+ D2 ^= F(D1, *K--);
+ D1 ^= F(D2, *K--);
+
+ if(K == &SK[1])
+ break;
+
+ D1 = FL (D1, *K--);
+ D2 = FLINV(D2, *K--);
+ }
+
+ D1 ^= *K--;
+ D2 ^= *K;
+
+ store_be(out, D2, D1);
+
+ in += 16;
+ out += 16;
+ }
+ }
+
+}
+
+}
+
+void Camellia_128::encrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ Camellia_F::encrypt(in, out, blocks, SK);
+ }
+
+void Camellia_192::encrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ Camellia_F::encrypt(in, out, blocks, SK);
+ }
+
+void Camellia_256::encrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ Camellia_F::encrypt(in, out, blocks, SK);
+ }
+
+void Camellia_128::decrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ Camellia_F::decrypt(in, out, blocks, SK);
+ }
+
+void Camellia_192::decrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ Camellia_F::decrypt(in, out, blocks, SK);
+ }
+
+void Camellia_256::decrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ Camellia_F::decrypt(in, out, blocks, SK);
+ }
+
+void Camellia_128::key_schedule(const byte key[], size_t length)
+ {
+ Camellia_F::key_schedule(SK, key, length);
+ }
+
+void Camellia_192::key_schedule(const byte key[], size_t length)
+ {
+ Camellia_F::key_schedule(SK, key, length);
+ }
+
+void Camellia_256::key_schedule(const byte key[], size_t length)
+ {
+ Camellia_F::key_schedule(SK, key, length);
+ }
+
}
diff --git a/src/block/camellia/camellia.h b/src/block/camellia/camellia.h
index aaf3ad9e3..9ce305983 100644
--- a/src/block/camellia/camellia.h
+++ b/src/block/camellia/camellia.h
@@ -13,17 +13,53 @@
namespace Botan {
/**
-* Camellia
+* Camellia-128
+*/
+class BOTAN_DLL Camellia_128 : public Block_Cipher_Fixed_Params<16, 16>
+ {
+ public:
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+
+ void clear() { SK.clear(); }
+ std::string name() const { return "Camellia-128"; }
+ BlockCipher* clone() const { return new Camellia_128; }
+ private:
+ void key_schedule(const byte key[], size_t length);
+
+ SecureVector<u64bit> SK;
+ };
+
+/**
+* Camellia-192
+*/
+class BOTAN_DLL Camellia_192 : public Block_Cipher_Fixed_Params<16, 24>
+ {
+ public:
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+
+ void clear() { SK.clear(); }
+ std::string name() const { return "Camellia-192"; }
+ BlockCipher* clone() const { return new Camellia_192; }
+ private:
+ void key_schedule(const byte key[], size_t length);
+
+ SecureVector<u64bit> SK;
+ };
+
+/**
+* Camellia-256
*/
-class BOTAN_DLL Camellia : public Block_Cipher_Fixed_Params<16, 16, 32, 8>
+class BOTAN_DLL Camellia_256 : public Block_Cipher_Fixed_Params<16, 32>
{
public:
void encrypt_n(const byte in[], byte out[], size_t blocks) const;
void decrypt_n(const byte in[], byte out[], size_t blocks) const;
void clear() { SK.clear(); }
- std::string name() const { return "Camellia"; }
- BlockCipher* clone() const { return new Camellia; }
+ std::string name() const { return "Camellia-256"; }
+ BlockCipher* clone() const { return new Camellia_256; }
private:
void key_schedule(const byte key[], size_t length);
diff --git a/src/engine/core_engine/lookup_block.cpp b/src/engine/core_engine/lookup_block.cpp
index c27a13237..c46d4f4cd 100644
--- a/src/engine/core_engine/lookup_block.cpp
+++ b/src/engine/core_engine/lookup_block.cpp
@@ -135,8 +135,12 @@ BlockCipher* Core_Engine::find_block_cipher(const SCAN_Name& request,
#endif
#if defined(BOTAN_HAS_CAMELLIA)
- if(request.algo_name() == "Camellia")
- return new Camellia;
+ if(request.algo_name() == "Camellia-128")
+ return new Camellia_128;
+ if(request.algo_name() == "Camellia-192")
+ return new Camellia_192;
+ if(request.algo_name() == "Camellia-256")
+ return new Camellia_256;
#endif
#if defined(BOTAN_HAS_CAST)