Botan
1.11.15
|
00001 /* 00002 * Lion 00003 * (C) 1999-2007,2014 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/block_utils.h> 00009 #include <botan/lion.h> 00010 #include <botan/parsing.h> 00011 00012 namespace Botan { 00013 00014 namespace { 00015 00016 Lion* make_lion(const BlockCipher::Spec& spec) 00017 { 00018 if(spec.arg_count_between(2, 3)) 00019 { 00020 std::unique_ptr<HashFunction> hash(Algo_Registry<HashFunction>::global_registry().make(spec.arg(0))); 00021 std::unique_ptr<StreamCipher> stream(Algo_Registry<StreamCipher>::global_registry().make(spec.arg(1))); 00022 00023 if(hash && stream) 00024 { 00025 const size_t block_size = spec.arg_as_integer(2, 1024); 00026 return new Lion(hash.release(), stream.release(), block_size); 00027 } 00028 } 00029 return nullptr; 00030 } 00031 00032 } 00033 00034 BOTAN_REGISTER_NAMED_T(BlockCipher, "Lion", Lion, make_lion); 00035 00036 /* 00037 * Lion Encryption 00038 */ 00039 void Lion::encrypt_n(const byte in[], byte out[], size_t blocks) const 00040 { 00041 const size_t LEFT_SIZE = left_size(); 00042 const size_t RIGHT_SIZE = right_size(); 00043 00044 secure_vector<byte> buffer_vec(LEFT_SIZE); 00045 byte* buffer = &buffer_vec[0]; 00046 00047 for(size_t i = 0; i != blocks; ++i) 00048 { 00049 xor_buf(buffer, in, &m_key1[0], LEFT_SIZE); 00050 m_cipher->set_key(buffer, LEFT_SIZE); 00051 m_cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); 00052 00053 m_hash->update(out + LEFT_SIZE, RIGHT_SIZE); 00054 m_hash->final(buffer); 00055 xor_buf(out, in, buffer, LEFT_SIZE); 00056 00057 xor_buf(buffer, out, &m_key2[0], LEFT_SIZE); 00058 m_cipher->set_key(buffer, LEFT_SIZE); 00059 m_cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE); 00060 00061 in += m_block_size; 00062 out += m_block_size; 00063 } 00064 } 00065 00066 /* 00067 * Lion Decryption 00068 */ 00069 void Lion::decrypt_n(const byte in[], byte out[], size_t blocks) const 00070 { 00071 const size_t LEFT_SIZE = left_size(); 00072 const size_t RIGHT_SIZE = right_size(); 00073 00074 secure_vector<byte> buffer_vec(LEFT_SIZE); 00075 byte* buffer = &buffer_vec[0]; 00076 00077 for(size_t i = 0; i != blocks; ++i) 00078 { 00079 xor_buf(buffer, in, &m_key2[0], LEFT_SIZE); 00080 m_cipher->set_key(buffer, LEFT_SIZE); 00081 m_cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); 00082 00083 m_hash->update(out + LEFT_SIZE, RIGHT_SIZE); 00084 m_hash->final(buffer); 00085 xor_buf(out, in, buffer, LEFT_SIZE); 00086 00087 xor_buf(buffer, out, &m_key1[0], LEFT_SIZE); 00088 m_cipher->set_key(buffer, LEFT_SIZE); 00089 m_cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE); 00090 00091 in += m_block_size; 00092 out += m_block_size; 00093 } 00094 } 00095 00096 /* 00097 * Lion Key Schedule 00098 */ 00099 void Lion::key_schedule(const byte key[], size_t length) 00100 { 00101 clear(); 00102 00103 const size_t half = length / 2; 00104 copy_mem(&m_key1[0], key, half); 00105 copy_mem(&m_key2[0], key + half, half); 00106 } 00107 00108 /* 00109 * Return the name of this type 00110 */ 00111 std::string Lion::name() const 00112 { 00113 return "Lion(" + m_hash->name() + "," + 00114 m_cipher->name() + "," + 00115 std::to_string(block_size()) + ")"; 00116 } 00117 00118 /* 00119 * Return a clone of this object 00120 */ 00121 BlockCipher* Lion::clone() const 00122 { 00123 return new Lion(m_hash->clone(), m_cipher->clone(), block_size()); 00124 } 00125 00126 /* 00127 * Clear memory of sensitive data 00128 */ 00129 void Lion::clear() 00130 { 00131 zeroise(m_key1); 00132 zeroise(m_key2); 00133 m_hash->clear(); 00134 m_cipher->clear(); 00135 } 00136 00137 /* 00138 * Lion Constructor 00139 */ 00140 Lion::Lion(HashFunction* hash, StreamCipher* cipher, size_t block_size) : 00141 m_block_size(std::max<size_t>(2*hash->output_length() + 1, block_size)), 00142 m_hash(hash), 00143 m_cipher(cipher) 00144 { 00145 if(2*left_size() + 1 > m_block_size) 00146 throw Invalid_Argument(name() + ": Chosen block size is too small"); 00147 00148 if(!m_cipher->valid_keylength(left_size())) 00149 throw Invalid_Argument(name() + ": This stream/hash combo is invalid"); 00150 00151 m_key1.resize(left_size()); 00152 m_key2.resize(left_size()); 00153 } 00154 00155 }