From 88c76ea4e1352763ccd2525506560417ce7fe72c Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 7 Jul 2020 22:53:54 +0200 Subject: [PATCH] encryption sink transformed to out stream and in stream --- src/common/encryption_filter.cpp | 18 +-- src/common/encryption_filter.h | 180 +++++++++++++++++++++--- tests/unit_tests/chacha_stream_test.cpp | 24 +++- 3 files changed, 184 insertions(+), 38 deletions(-) diff --git a/src/common/encryption_filter.cpp b/src/common/encryption_filter.cpp index b766059b..8861fa8c 100644 --- a/src/common/encryption_filter.cpp +++ b/src/common/encryption_filter.cpp @@ -4,20 +4,4 @@ #include "encryption_filter.h" -#include "crypto/chacha8_stream.h" - -encrypt_chacha_filter::encrypt_chacha_filter(std::string const &pass, const crypto::chacha8_iv& iv):m_iv(iv), m_ctx(AUTO_VAL_INIT(m_ctx)) -{ - crypto::generate_chacha8_key(pass, m_key); - ECRYPT_keysetup(&m_ctx, &m_key.data[0], sizeof(m_key.data) * 8, sizeof(m_iv.data)*8); - ECRYPT_ivsetup(&m_ctx, &m_iv.data[0]); -} - -//bool encrypt_chacha_filter::flush() const - - - -encrypt_chacha_filter::~encrypt_chacha_filter() -{ - -} +#include "crypto/chacha8_stream.h" \ No newline at end of file diff --git a/src/common/encryption_filter.h b/src/common/encryption_filter.h index d02f7e32..b2e03f5d 100644 --- a/src/common/encryption_filter.h +++ b/src/common/encryption_filter.h @@ -13,22 +13,31 @@ #include "crypto/chacha8_stream.h" -class encrypt_chacha_filter + +/************************************************************************/ +/* */ +/************************************************************************/ + +class encrypt_chacha_processer_base { public: typedef char char_type; //typedef boost::iostreams::multichar_output_filter_tag category; //typedef boost::iostreams::flushable_tag category; - struct category: //public boost::iostreams::seekable_device_tag, - public boost::iostreams::multichar_output_filter_tag, - public boost::iostreams::flushable_tag - { }; - encrypt_chacha_filter(std::string const &pass, const crypto::chacha8_iv& iv); - ~encrypt_chacha_filter(); + encrypt_chacha_processer_base(std::string const &pass, const crypto::chacha8_iv& iv) :m_iv(iv), m_ctx(AUTO_VAL_INIT(m_ctx)) + { + crypto::generate_chacha8_key(pass, m_key); + ECRYPT_keysetup(&m_ctx, &m_key.data[0], sizeof(m_key.data) * 8, sizeof(m_iv.data) * 8); + ECRYPT_ivsetup(&m_ctx, &m_iv.data[0]); + } + ~encrypt_chacha_processer_base() + { - template - std::streamsize write(t_sink& snk, char_type const * const buf, std::streamsize const n) const + } + + template + std::streamsize process(char_type const * const buf, std::streamsize const n, cb_handler cb) const { if (n == 0) return n; @@ -36,8 +45,9 @@ public: { std::vector buff(n); ECRYPT_encrypt_blocks(&m_ctx, (u8*)buf, (u8*)&buff[0], (u32)(n / ECRYPT_BLOCKLENGTH)); - boost::iostreams::write(snk, &buff[0], n); + cb(&buff[0], n); //m_underlying_stream.write(&buff[0], n); + return n; } else { @@ -48,21 +58,22 @@ public: std::vector buff(encr_count); ECRYPT_encrypt_blocks(&m_ctx, (u8*)m_buff.data(), (u8*)&buff[0], (u32)(m_buff.size() / ECRYPT_BLOCKLENGTH)); //m_underlying_stream.write(&buff[0], encr_count); - boost::iostreams::write(snk, &buff[0], encr_count); + cb(&buff[0], encr_count); m_buff.erase(0, encr_count); + return encr_count; } - return n; + } - template - bool flush(Sink& snk) + template + bool flush(cb_handler cb) { if (m_buff.empty()) return true; std::vector buff(m_buff.size()); ECRYPT_encrypt_bytes(&m_ctx, (u8*)m_buff.data(), (u8*)&buff[0], (u32)m_buff.size()); - boost::iostreams::write(snk, &buff[0], m_buff.size()); + cb(&buff[0], m_buff.size()); //m_underlying_stream.write(&buff[0], m_buff.size()); return true; } @@ -73,4 +84,141 @@ private: //std::ostream &m_underlying_stream; crypto::chacha8_key m_key; mutable std::string m_buff; -}; \ No newline at end of file +}; + +/************************************************************************/ +/* */ +/************************************************************************/ + + +class encrypt_chacha_out_filter: public encrypt_chacha_processer_base +{ +public: + typedef char char_type; + struct category: + public boost::iostreams::multichar_output_filter_tag, + public boost::iostreams::flushable_tag + { }; + + encrypt_chacha_out_filter(std::string const &pass, const crypto::chacha8_iv& iv) :encrypt_chacha_processer_base(pass, iv) + { + } + ~encrypt_chacha_out_filter() + { + } + + template + std::streamsize write(t_sink& snk, char_type const * const buf, std::streamsize const n) const + { + return encrypt_chacha_processer_base::process(buf, n, [&](char_type const * const buf_lambda, std::streamsize const n_lambda) { + boost::iostreams::write(snk, &buf_lambda[0], n_lambda); + }); + } + + template + bool flush(Sink& snk) + { + + encrypt_chacha_processer_base::flush([&](char_type const * const buf_lambda, std::streamsize const n_lambda) { + boost::iostreams::write(snk, &buf_lambda[0], n_lambda); + }); + return true; + } + +private: +}; + + +/************************************************************************/ +/* */ +/************************************************************************/ + +class encrypt_chacha_in_filter : public encrypt_chacha_processer_base +{ +public: + typedef char char_type; + struct category: //public boost::iostreams::seekable_device_tag, + public boost::iostreams::multichar_input_filter_tag, + public boost::iostreams::flushable_tag + //public boost::iostreams::seekable_filter_tag + { }; + encrypt_chacha_in_filter(std::string const &pass, const crypto::chacha8_iv& iv) :encrypt_chacha_processer_base(pass, iv), m_was_eof(false) + { + } + ~encrypt_chacha_in_filter() + { + } + + template + std::streamsize read(Source& src, char* s, std::streamsize n) + { + std::streamsize result = 0; + if ((result = boost::iostreams::read(src, s, n)) == -1) + { + if (!m_was_eof) + { + m_was_eof = true; + std::streamsize written_butes = 0; + encrypt_chacha_processer_base::flush([&](char_type const * const buf_lambda, std::streamsize const n_lambda) { + return written_butes = withdraw_to_read_buff(s, n, buf_lambda, n_lambda); + }); + if (!written_butes) + return -1; + return written_butes; + } + else + { + if (!m_buff.size()) + { + return -1; + } + else + { + return withdraw_to_read_buff(s, n, "", 0); + } + } + } + + return encrypt_chacha_processer_base::process(s, result, [&](char_type const * const buf_lambda, std::streamsize const n_lambda) { + return withdraw_to_read_buff(s, n, buf_lambda, n_lambda); + }); + } + + + template + bool flush(Sink& snk) + { + encrypt_chacha_processer_base::flush([&](char_type const * const buf_lambda, std::streamsize const n_lambda) { + boost::iostreams::write(snk, &buf_lambda[0], n_lambda); + }); + return true; + } + +private: + std::streamsize withdraw_to_read_buff(char* s, std::streamsize n, char_type const * const buf_lambda, std::streamsize const n_lambda) + { + if (m_buff.size()) + { + //need to use m_buff anyway + m_buff.append(buf_lambda, n_lambda); + size_t copy_size = n > m_buff.size() ? m_buff.size() : n; + std::memcpy(s, buf_lambda, copy_size); + m_buff.erase(0, copy_size); + return copy_size; + } + else + { + size_t copy_size = n > n_lambda ? n_lambda : n; + std::memcpy(s, buf_lambda, copy_size); + if (n_lambda > copy_size) + { + //need to add tail to m_buff + m_buff.append(buf_lambda + copy_size, n_lambda - copy_size); + } + return copy_size; + } + } + + std::string m_buff; + bool m_was_eof; +}; diff --git a/tests/unit_tests/chacha_stream_test.cpp b/tests/unit_tests/chacha_stream_test.cpp index 3c0575dd..4f8b2298 100644 --- a/tests/unit_tests/chacha_stream_test.cpp +++ b/tests/unit_tests/chacha_stream_test.cpp @@ -72,11 +72,24 @@ TEST(chacha_stream_test, chacha_stream_test) // std::cout << "OK" << std::endl; // } +// struct category_out: //public boost::iostreams::seekable_device_tag, +// public boost::iostreams::multichar_output_filter_tag, +// public boost::iostreams::flushable_tag +// //public boost::iostreams::seekable_filter_tag +// { }; + +// struct category_in : //public boost::iostreams::seekable_device_tag, +// public boost::iostreams::multichar_output_filter_tag, +// public boost::iostreams::flushable_tag +// //public boost::iostreams::seekable_filter_tag +// { }; + + crypto::chacha8_iv iv = crypto::rand(); boost::filesystem::ofstream store_data_file; store_data_file.open("./test.bin", std::ios_base::binary | std::ios_base::out | std::ios::trunc); - encrypt_chacha_filter encrypt_filter("pass", iv); + encrypt_chacha_out_filter encrypt_filter("pass", iv); //boost::iostreams::stream outputStream(sink_encrypt); boost::iostreams::filtering_ostream out; out.push(encrypt_filter); @@ -88,16 +101,17 @@ TEST(chacha_stream_test, chacha_stream_test) boost::filesystem::ifstream data_file; data_file.open("./test.bin", std::ios_base::binary | std::ios_base::in); - encrypt_chacha_filter decrypt_filter("pass", iv); + encrypt_chacha_in_filter decrypt_filter("pass", iv); boost::iostreams::filtering_istream in; - in.push(boost::iostreams::invert(decrypt_filter)); + //in.push(boost::iostreams::invert(decrypt_filter)); + in.push(decrypt_filter); in.push(data_file); //todo: read from stream - auto size = buff_size; + size_t size = buff_size;//in.tellg(); std::string str(size, '\0'); // construct string to stream size - + //in.seekg(0); try { in.read(&str[0], size+1);