/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/cascade.h> |
9 | | |
10 | | namespace Botan { |
11 | | |
12 | | void Cascade_Cipher::encrypt_n(const uint8_t in[], uint8_t out[], |
13 | | size_t blocks) const |
14 | 0 | { |
15 | 0 | size_t c1_blocks = blocks * (block_size() / m_cipher1->block_size()); |
16 | 0 | size_t c2_blocks = blocks * (block_size() / m_cipher2->block_size()); |
17 | 0 |
|
18 | 0 | m_cipher1->encrypt_n(in, out, c1_blocks); |
19 | 0 | m_cipher2->encrypt_n(out, out, c2_blocks); |
20 | 0 | } |
21 | | |
22 | | void Cascade_Cipher::decrypt_n(const uint8_t in[], uint8_t out[], |
23 | | size_t blocks) const |
24 | 0 | { |
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 | 0 |
|
28 | 0 | m_cipher2->decrypt_n(in, out, c2_blocks); |
29 | 0 | m_cipher1->decrypt_n(out, out, c1_blocks); |
30 | 0 | } |
31 | | |
32 | | void Cascade_Cipher::key_schedule(const uint8_t key[], size_t) |
33 | 0 | { |
34 | 0 | const uint8_t* key2 = key + m_cipher1->maximum_keylength(); |
35 | 0 |
|
36 | 0 | m_cipher1->set_key(key , m_cipher1->maximum_keylength()); |
37 | 0 | m_cipher2->set_key(key2, m_cipher2->maximum_keylength()); |
38 | 0 | } |
39 | | |
40 | | void Cascade_Cipher::clear() |
41 | 0 | { |
42 | 0 | m_cipher1->clear(); |
43 | 0 | m_cipher2->clear(); |
44 | 0 | } |
45 | | |
46 | | std::string Cascade_Cipher::name() const |
47 | 0 | { |
48 | 0 | return "Cascade(" + m_cipher1->name() + "," + m_cipher2->name() + ")"; |
49 | 0 | } |
50 | | |
51 | | BlockCipher* Cascade_Cipher::clone() const |
52 | 0 | { |
53 | 0 | return new Cascade_Cipher(m_cipher1->clone(), |
54 | 0 | m_cipher2->clone()); |
55 | 0 | } |
56 | | |
57 | | namespace { |
58 | | |
59 | | size_t euclids_algorithm(size_t a, size_t b) |
60 | 0 | { |
61 | 0 | while(b != 0) |
62 | 0 | { |
63 | 0 | size_t t = b; |
64 | 0 | b = a % b; |
65 | 0 | a = t; |
66 | 0 | } |
67 | 0 |
|
68 | 0 | return a; |
69 | 0 | } |
70 | | |
71 | | size_t block_size_for_cascade(size_t bs, size_t bs2) |
72 | 0 | { |
73 | 0 | if(bs == bs2) |
74 | 0 | return bs; |
75 | 0 | |
76 | 0 | const size_t gcd = euclids_algorithm(bs, bs2); |
77 | 0 |
|
78 | 0 | return (bs * bs2) / gcd; |
79 | 0 | } |
80 | | |
81 | | } |
82 | | |
83 | | Cascade_Cipher::Cascade_Cipher(BlockCipher* c1, BlockCipher* c2) : |
84 | | m_cipher1(c1), m_cipher2(c2) |
85 | 0 | { |
86 | 0 | m_block = block_size_for_cascade(c1->block_size(), c2->block_size()); |
87 | 0 |
|
88 | 0 | BOTAN_ASSERT(m_block % c1->block_size() == 0 && |
89 | 0 | m_block % c2->block_size() == 0, |
90 | 0 | "Combined block size is a multiple of each ciphers block"); |
91 | 0 | } |
92 | | |
93 | | } |