Botan  1.11.15
src/lib/block/lion/lion.cpp
Go to the documentation of this file.
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 }