summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/filters/cipher_filter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/lib/filters/cipher_filter.cpp')
-rw-r--r--comm/third_party/botan/src/lib/filters/cipher_filter.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/filters/cipher_filter.cpp b/comm/third_party/botan/src/lib/filters/cipher_filter.cpp
new file mode 100644
index 0000000000..720aeac6fd
--- /dev/null
+++ b/comm/third_party/botan/src/lib/filters/cipher_filter.cpp
@@ -0,0 +1,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/filters.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);
+ }
+
+}