1 /*
2 * Lion
3 * (C) 1999-2007,2014 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/lion.h>
9 #include <botan/exceptn.h>
10 
11 namespace Botan {
12 
13 /*
14 * Lion Encryption
15 */
encrypt_n(const uint8_t in[],uint8_t out[],size_t blocks) const16 void Lion::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
17    {
18    verify_key_set(m_key1.empty() == false);
19 
20    const size_t LEFT_SIZE = left_size();
21    const size_t RIGHT_SIZE = right_size();
22 
23    secure_vector<uint8_t> buffer_vec(LEFT_SIZE);
24    uint8_t* buffer = buffer_vec.data();
25 
26    for(size_t i = 0; i != blocks; ++i)
27       {
28       xor_buf(buffer, in, m_key1.data(), LEFT_SIZE);
29       m_cipher->set_key(buffer, LEFT_SIZE);
30       m_cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);
31 
32       m_hash->update(out + LEFT_SIZE, RIGHT_SIZE);
33       m_hash->final(buffer);
34       xor_buf(out, in, buffer, LEFT_SIZE);
35 
36       xor_buf(buffer, out, m_key2.data(), LEFT_SIZE);
37       m_cipher->set_key(buffer, LEFT_SIZE);
38       m_cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE);
39 
40       in += m_block_size;
41       out += m_block_size;
42       }
43    }
44 
45 /*
46 * Lion Decryption
47 */
decrypt_n(const uint8_t in[],uint8_t out[],size_t blocks) const48 void Lion::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
49    {
50    verify_key_set(m_key1.empty() == false);
51 
52    const size_t LEFT_SIZE = left_size();
53    const size_t RIGHT_SIZE = right_size();
54 
55    secure_vector<uint8_t> buffer_vec(LEFT_SIZE);
56    uint8_t* buffer = buffer_vec.data();
57 
58    for(size_t i = 0; i != blocks; ++i)
59       {
60       xor_buf(buffer, in, m_key2.data(), LEFT_SIZE);
61       m_cipher->set_key(buffer, LEFT_SIZE);
62       m_cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);
63 
64       m_hash->update(out + LEFT_SIZE, RIGHT_SIZE);
65       m_hash->final(buffer);
66       xor_buf(out, in, buffer, LEFT_SIZE);
67 
68       xor_buf(buffer, out, m_key1.data(), LEFT_SIZE);
69       m_cipher->set_key(buffer, LEFT_SIZE);
70       m_cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE);
71 
72       in += m_block_size;
73       out += m_block_size;
74       }
75    }
76 
77 /*
78 * Lion Key Schedule
79 */
key_schedule(const uint8_t key[],size_t length)80 void Lion::key_schedule(const uint8_t key[], size_t length)
81    {
82    clear();
83 
84    const size_t half = length / 2;
85 
86    m_key1.resize(left_size());
87    m_key2.resize(left_size());
88    clear_mem(m_key1.data(), m_key1.size());
89    clear_mem(m_key2.data(), m_key2.size());
90    copy_mem(m_key1.data(), key, half);
91    copy_mem(m_key2.data(), key + half, half);
92    }
93 
94 /*
95 * Return the name of this type
96 */
name() const97 std::string Lion::name() const
98    {
99    return "Lion(" + m_hash->name() + "," +
100                     m_cipher->name() + "," +
101                     std::to_string(block_size()) + ")";
102    }
103 
104 /*
105 * Return a clone of this object
106 */
clone() const107 BlockCipher* Lion::clone() const
108    {
109    return new Lion(m_hash->clone(), m_cipher->clone(), block_size());
110    }
111 
112 /*
113 * Clear memory of sensitive data
114 */
clear()115 void Lion::clear()
116    {
117    zap(m_key1);
118    zap(m_key2);
119    m_hash->clear();
120    m_cipher->clear();
121    }
122 
123 /*
124 * Lion Constructor
125 */
Lion(HashFunction * hash,StreamCipher * cipher,size_t bs)126 Lion::Lion(HashFunction* hash, StreamCipher* cipher, size_t bs) :
127    m_block_size(std::max<size_t>(2*hash->output_length() + 1, bs)),
128    m_hash(hash),
129    m_cipher(cipher)
130    {
131    if(2*left_size() + 1 > m_block_size)
132       throw Invalid_Argument(name() + ": Chosen block size is too small");
133 
134    if(!m_cipher->valid_keylength(left_size()))
135       throw Invalid_Argument(name() + ": This stream/hash combo is invalid");
136    }
137 
138 }
139