aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)