Botan 3.13.0
Crypto and TLS for C&
cascade.cpp
Go to the documentation of this file.
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/buffer_slicer.h>
11#include <botan/internal/fmt.h>
12#include <botan/internal/int_utils.h>
13#include <numeric>
14
15namespace Botan {
16
17namespace {
18
19size_t cascade_block_size(size_t b1, size_t b2) {
20 // std::lcm itself is undefined if the result is not representable
21 return mul_or_throw(b1 / std::gcd(b1, b2), b2, "Cascade combined block size is too large");
22}
23
24} // namespace
25
26void Cascade_Cipher::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
27 const size_t c1_blocks = blocks * (block_size() / m_cipher1->block_size());
28 const size_t c2_blocks = blocks * (block_size() / m_cipher2->block_size());
29
30 m_cipher1->encrypt_n(in, out, c1_blocks);
31 m_cipher2->encrypt_n(out, out, c2_blocks);
32}
33
34void Cascade_Cipher::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
35 const size_t c1_blocks = blocks * (block_size() / m_cipher1->block_size());
36 const size_t c2_blocks = blocks * (block_size() / m_cipher2->block_size());
37
38 m_cipher2->decrypt_n(in, out, c2_blocks);
39 m_cipher1->decrypt_n(out, out, c1_blocks);
40}
41
42void Cascade_Cipher::key_schedule(std::span<const uint8_t> key) {
43 BufferSlicer keys(key);
44
45 m_cipher1->set_key(keys.take(m_cipher1->maximum_keylength()));
46 m_cipher2->set_key(keys.take(m_cipher2->maximum_keylength()));
47}
48
50 m_cipher1->clear();
51 m_cipher2->clear();
52}
53
54std::string Cascade_Cipher::name() const {
55 return fmt("Cascade({},{})", m_cipher1->name(), m_cipher2->name());
56}
57
59 return m_cipher1->has_keying_material() && m_cipher2->has_keying_material();
60}
61
62std::unique_ptr<BlockCipher> Cascade_Cipher::new_object() const {
63 return std::make_unique<Cascade_Cipher>(m_cipher1->new_object(), m_cipher2->new_object());
64}
65
66Cascade_Cipher::Cascade_Cipher(std::unique_ptr<BlockCipher> cipher1, std::unique_ptr<BlockCipher> cipher2) :
67 m_cipher1(std::move(cipher1)),
68 m_cipher2(std::move(cipher2)),
69 m_block_size(cascade_block_size(m_cipher1->block_size(), m_cipher2->block_size())) {
70 // TODO(Botan4) require the block lengths of the two ciphers be the same
71 BOTAN_ASSERT(m_block_size % m_cipher1->block_size() == 0 && m_block_size % m_cipher2->block_size() == 0,
72 "Combined block size is a multiple of each ciphers block");
73}
74
75} // namespace Botan
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
bool has_keying_material() const override
Definition cascade.cpp:58
std::string name() const override
Definition cascade.cpp:54
Cascade_Cipher(std::unique_ptr< BlockCipher > cipher1, std::unique_ptr< BlockCipher > cipher2)
Definition cascade.cpp:66
std::unique_ptr< BlockCipher > new_object() const override
Definition cascade.cpp:62
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition cascade.cpp:26
void clear() override
Definition cascade.cpp:49
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition cascade.cpp:34
size_t block_size() const override
Definition cascade.h:23
constexpr T mul_or_throw(T a, T b, std::string_view msg)
Definition int_utils.h:81
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53