/src/botan/src/lib/block/cascade/cascade.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Block Cipher Cascade |
3 | | * (C) 2010 Jack Lloyd |
4 | | * |
5 | | * Botan is released under the Simplified BSD License (see license.txt) |
6 | | */ |
7 | | |
8 | | #include <botan/internal/cascade.h> |
9 | | |
10 | | #include <botan/internal/fmt.h> |
11 | | #include <botan/internal/stl_util.h> |
12 | | #include <numeric> |
13 | | |
14 | | namespace Botan { |
15 | | |
16 | 0 | void Cascade_Cipher::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { |
17 | 0 | size_t c1_blocks = blocks * (block_size() / m_cipher1->block_size()); |
18 | 0 | size_t c2_blocks = blocks * (block_size() / m_cipher2->block_size()); |
19 | |
|
20 | 0 | m_cipher1->encrypt_n(in, out, c1_blocks); |
21 | 0 | m_cipher2->encrypt_n(out, out, c2_blocks); |
22 | 0 | } |
23 | | |
24 | 0 | void Cascade_Cipher::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { |
25 | 0 | size_t c1_blocks = blocks * (block_size() / m_cipher1->block_size()); |
26 | 0 | size_t c2_blocks = blocks * (block_size() / m_cipher2->block_size()); |
27 | |
|
28 | 0 | m_cipher2->decrypt_n(in, out, c2_blocks); |
29 | 0 | m_cipher1->decrypt_n(out, out, c1_blocks); |
30 | 0 | } |
31 | | |
32 | 0 | void Cascade_Cipher::key_schedule(std::span<const uint8_t> key) { |
33 | 0 | BufferSlicer keys(key); |
34 | |
|
35 | 0 | m_cipher1->set_key(keys.take(m_cipher1->maximum_keylength())); |
36 | 0 | m_cipher2->set_key(keys.take(m_cipher2->maximum_keylength())); |
37 | 0 | } |
38 | | |
39 | 0 | void Cascade_Cipher::clear() { |
40 | 0 | m_cipher1->clear(); |
41 | 0 | m_cipher2->clear(); |
42 | 0 | } |
43 | | |
44 | 0 | std::string Cascade_Cipher::name() const { |
45 | 0 | return fmt("Cascade({},{})", m_cipher1->name(), m_cipher2->name()); |
46 | 0 | } |
47 | | |
48 | 0 | bool Cascade_Cipher::has_keying_material() const { |
49 | 0 | return m_cipher1->has_keying_material() && m_cipher2->has_keying_material(); |
50 | 0 | } |
51 | | |
52 | 0 | std::unique_ptr<BlockCipher> Cascade_Cipher::new_object() const { |
53 | 0 | return std::make_unique<Cascade_Cipher>(m_cipher1->new_object(), m_cipher2->new_object()); |
54 | 0 | } |
55 | | |
56 | | Cascade_Cipher::Cascade_Cipher(std::unique_ptr<BlockCipher> cipher1, std::unique_ptr<BlockCipher> cipher2) : |
57 | | m_cipher1(std::move(cipher1)), |
58 | | m_cipher2(std::move(cipher2)), |
59 | 0 | m_block_size(std::lcm(m_cipher1->block_size(), m_cipher2->block_size())) { |
60 | 0 | BOTAN_ASSERT(m_block_size % m_cipher1->block_size() == 0 && m_block_size % m_cipher2->block_size() == 0, |
61 | 0 | "Combined block size is a multiple of each ciphers block"); |
62 | 0 | } |
63 | | |
64 | | } // namespace Botan |