diff options
-rw-r--r-- | checks/validate.dat | 22 | ||||
-rw-r--r-- | src/block/camellia/camellia.cpp | 226 | ||||
-rw-r--r-- | src/block/camellia/camellia.h | 44 | ||||
-rw-r--r-- | src/engine/core_engine/lookup_block.cpp | 8 |
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) |