aboutsummaryrefslogtreecommitdiffstats
path: root/src/block/camellia
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 /src/block/camellia
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.
Diffstat (limited to 'src/block/camellia')
-rw-r--r--src/block/camellia/camellia.cpp226
-rw-r--r--src/block/camellia/camellia.h44
2 files changed, 173 insertions, 97 deletions
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);