/src/botan/src/lib/block/lion/lion.cpp
Line  | Count  | Source (jump to first uncovered line)  | 
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/internal/lion.h>  | 
9  |  |  | 
10  |  | #include <botan/exceptn.h>  | 
11  |  | #include <botan/internal/fmt.h>  | 
12  |  |  | 
13  |  | namespace Botan { | 
14  |  |  | 
15  |  | /*  | 
16  |  | * Lion Encryption  | 
17  |  | */  | 
18  | 0  | void Lion::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { | 
19  | 0  |    assert_key_material_set();  | 
20  |  | 
  | 
21  | 0  |    const size_t LEFT_SIZE = left_size();  | 
22  | 0  |    const size_t RIGHT_SIZE = right_size();  | 
23  |  | 
  | 
24  | 0  |    secure_vector<uint8_t> buffer_vec(LEFT_SIZE);  | 
25  | 0  |    uint8_t* buffer = buffer_vec.data();  | 
26  |  | 
  | 
27  | 0  |    for(size_t i = 0; i != blocks; ++i) { | 
28  | 0  |       xor_buf(buffer, in, m_key1.data(), LEFT_SIZE);  | 
29  | 0  |       m_cipher->set_key(buffer, LEFT_SIZE);  | 
30  | 0  |       m_cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);  | 
31  |  | 
  | 
32  | 0  |       m_hash->update(out + LEFT_SIZE, RIGHT_SIZE);  | 
33  | 0  |       m_hash->final(buffer);  | 
34  | 0  |       xor_buf(out, in, buffer, LEFT_SIZE);  | 
35  |  | 
  | 
36  | 0  |       xor_buf(buffer, out, m_key2.data(), LEFT_SIZE);  | 
37  | 0  |       m_cipher->set_key(buffer, LEFT_SIZE);  | 
38  | 0  |       m_cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE);  | 
39  |  | 
  | 
40  | 0  |       in += m_block_size;  | 
41  | 0  |       out += m_block_size;  | 
42  | 0  |    }  | 
43  | 0  | }  | 
44  |  |  | 
45  |  | /*  | 
46  |  | * Lion Decryption  | 
47  |  | */  | 
48  | 0  | void Lion::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { | 
49  | 0  |    assert_key_material_set();  | 
50  |  | 
  | 
51  | 0  |    const size_t LEFT_SIZE = left_size();  | 
52  | 0  |    const size_t RIGHT_SIZE = right_size();  | 
53  |  | 
  | 
54  | 0  |    secure_vector<uint8_t> buffer_vec(LEFT_SIZE);  | 
55  | 0  |    uint8_t* buffer = buffer_vec.data();  | 
56  |  | 
  | 
57  | 0  |    for(size_t i = 0; i != blocks; ++i) { | 
58  | 0  |       xor_buf(buffer, in, m_key2.data(), LEFT_SIZE);  | 
59  | 0  |       m_cipher->set_key(buffer, LEFT_SIZE);  | 
60  | 0  |       m_cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);  | 
61  |  | 
  | 
62  | 0  |       m_hash->update(out + LEFT_SIZE, RIGHT_SIZE);  | 
63  | 0  |       m_hash->final(buffer);  | 
64  | 0  |       xor_buf(out, in, buffer, LEFT_SIZE);  | 
65  |  | 
  | 
66  | 0  |       xor_buf(buffer, out, m_key1.data(), LEFT_SIZE);  | 
67  | 0  |       m_cipher->set_key(buffer, LEFT_SIZE);  | 
68  | 0  |       m_cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE);  | 
69  |  | 
  | 
70  | 0  |       in += m_block_size;  | 
71  | 0  |       out += m_block_size;  | 
72  | 0  |    }  | 
73  | 0  | }  | 
74  |  |  | 
75  | 0  | bool Lion::has_keying_material() const { | 
76  | 0  |    return !m_key1.empty() && !m_key2.empty();  | 
77  | 0  | }  | 
78  |  |  | 
79  |  | /*  | 
80  |  | * Lion Key Schedule  | 
81  |  | */  | 
82  | 0  | void Lion::key_schedule(std::span<const uint8_t> key) { | 
83  | 0  |    clear();  | 
84  |  | 
  | 
85  | 0  |    const size_t half = key.size() / 2;  | 
86  |  | 
  | 
87  | 0  |    m_key1.resize(left_size());  | 
88  | 0  |    m_key2.resize(left_size());  | 
89  | 0  |    clear_mem(m_key1.data(), m_key1.size());  | 
90  | 0  |    clear_mem(m_key2.data(), m_key2.size());  | 
91  | 0  |    copy_mem(m_key1.data(), key.data(), half);  | 
92  | 0  |    copy_mem(m_key2.data(), key.subspan(half, half).data(), half);  | 
93  | 0  | }  | 
94  |  |  | 
95  |  | /*  | 
96  |  | * Return the name of this type  | 
97  |  | */  | 
98  | 0  | std::string Lion::name() const { | 
99  | 0  |    return fmt("Lion({},{},{})", m_hash->name(), m_cipher->name(), block_size()); | 
100  | 0  | }  | 
101  |  |  | 
102  | 0  | std::unique_ptr<BlockCipher> Lion::new_object() const { | 
103  | 0  |    return std::make_unique<Lion>(m_hash->new_object(), m_cipher->new_object(), block_size());  | 
104  | 0  | }  | 
105  |  |  | 
106  |  | /*  | 
107  |  | * Clear memory of sensitive data  | 
108  |  | */  | 
109  | 0  | void Lion::clear() { | 
110  | 0  |    zap(m_key1);  | 
111  | 0  |    zap(m_key2);  | 
112  | 0  |    m_hash->clear();  | 
113  | 0  |    m_cipher->clear();  | 
114  | 0  | }  | 
115  |  |  | 
116  |  | /*  | 
117  |  | * Lion Constructor  | 
118  |  | */  | 
119  |  | Lion::Lion(std::unique_ptr<HashFunction> hash, std::unique_ptr<StreamCipher> cipher, size_t bs) :  | 
120  |  |       m_block_size(std::max<size_t>(2 * hash->output_length() + 1, bs)),  | 
121  |  |       m_hash(std::move(hash)),  | 
122  | 0  |       m_cipher(std::move(cipher)) { | 
123  | 0  |    if(2 * left_size() + 1 > m_block_size) { | 
124  | 0  |       throw Invalid_Argument(fmt("Block size {} is too small for {}", m_block_size, name())); | 
125  | 0  |    }  | 
126  |  |  | 
127  | 0  |    if(!m_cipher->valid_keylength(left_size())) { | 
128  | 0  |       throw Invalid_Argument(fmt("Lion does not support combining {} and {}", m_cipher->name(), m_hash->name())); | 
129  | 0  |    }  | 
130  | 0  | }  | 
131  |  |  | 
132  |  | }  // namespace Botan  |