1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
/*
* Filter interface for Cipher_Modes
* (C) 2013,2014,2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/cipher_filter.h>
#include <botan/internal/rounding.h>
namespace Botan {
namespace {
size_t choose_update_size(size_t update_granularity)
{
const size_t target_size = 1024;
if(update_granularity >= target_size)
return update_granularity;
return round_up(target_size, update_granularity);
}
}
Cipher_Mode_Filter::Cipher_Mode_Filter(Cipher_Mode* mode) :
Buffered_Filter(choose_update_size(mode->update_granularity()),
mode->minimum_final_size()),
m_mode(mode),
m_nonce(mode->default_nonce_length()),
m_buffer(m_mode->update_granularity())
{
}
std::string Cipher_Mode_Filter::name() const
{
return m_mode->name();
}
void Cipher_Mode_Filter::set_iv(const InitializationVector& iv)
{
m_nonce = unlock(iv.bits_of());
}
void Cipher_Mode_Filter::set_key(const SymmetricKey& key)
{
m_mode->set_key(key);
}
Key_Length_Specification Cipher_Mode_Filter::key_spec() const
{
return m_mode->key_spec();
}
bool Cipher_Mode_Filter::valid_iv_length(size_t length) const
{
return m_mode->valid_nonce_length(length);
}
void Cipher_Mode_Filter::write(const uint8_t input[], size_t input_length)
{
Buffered_Filter::write(input, input_length);
}
void Cipher_Mode_Filter::end_msg()
{
Buffered_Filter::end_msg();
}
void Cipher_Mode_Filter::start_msg()
{
if(m_nonce.empty() && !m_mode->valid_nonce_length(0))
throw Invalid_State("Cipher " + m_mode->name() + " requires a fresh nonce for each message");
m_mode->start(m_nonce);
m_nonce.clear();
}
void Cipher_Mode_Filter::buffered_block(const uint8_t input[], size_t input_length)
{
while(input_length)
{
const size_t take = std::min(m_mode->update_granularity(), input_length);
m_buffer.assign(input, input + take);
m_mode->update(m_buffer);
send(m_buffer);
input += take;
input_length -= take;
}
}
void Cipher_Mode_Filter::buffered_final(const uint8_t input[], size_t input_length)
{
secure_vector<uint8_t> buf(input, input + input_length);
m_mode->finish(buf);
send(buf);
}
}
|