diff --git a/src/common/encryption_filter.cpp b/src/common/encryption_filter.cpp new file mode 100644 index 00000000..b766059b --- /dev/null +++ b/src/common/encryption_filter.cpp @@ -0,0 +1,23 @@ +// Copyright (c) 2014-2019 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +#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() +{ + +} diff --git a/src/common/encryption_filter.h b/src/common/encryption_filter.h new file mode 100644 index 00000000..d02f7e32 --- /dev/null +++ b/src/common/encryption_filter.h @@ -0,0 +1,76 @@ +// Copyright (c) 2014-2018 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include +#include +#include +#include // sink_tag +#include "include_base_utils.h" +#include "crypto/chacha8.h" +#include "crypto/chacha8_stream.h" + + +class encrypt_chacha_filter +{ +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(); + + template + std::streamsize write(t_sink& snk, char_type const * const buf, std::streamsize const n) const + { + if (n == 0) + return n; + if (n%ECRYPT_BLOCKLENGTH == 0 && m_buff.empty()) + { + 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); + //m_underlying_stream.write(&buff[0], n); + } + else + { + m_buff.append(buf, n); + size_t encr_count = m_buff.size() - m_buff.size() % ECRYPT_BLOCKLENGTH; + if (!encr_count) + return n; + 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); + m_buff.erase(0, encr_count); + } + return n; + } + + template + bool flush(Sink& snk) + { + 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()); + //m_underlying_stream.write(&buff[0], m_buff.size()); + return true; + } + +private: + const crypto::chacha8_iv& m_iv; + mutable ECRYPT_ctx m_ctx; + //std::ostream &m_underlying_stream; + crypto::chacha8_key m_key; + mutable std::string m_buff; +}; \ No newline at end of file diff --git a/src/common/encryption_sink.cpp b/src/common/encryption_sink.cpp deleted file mode 100644 index 01f6824b..00000000 --- a/src/common/encryption_sink.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2014-2019 Zano Project -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - - -#include "encryption_sink.h" -#include "crypto/chacha8_stream.h" - -encrypt_chacha_sink::encrypt_chacha_sink(std::ostream &underlying_stream, std::string const &pass, const crypto::chacha8_iv& iv):m_iv(iv), m_underlying_stream(underlying_stream), 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]); -} - -std::streamsize encrypt_chacha_sink::write(char_type const * const buf, std::streamsize const n) const -{ - if (n == 0) - return n; - if (n%ECRYPT_BLOCKLENGTH == 0 && m_buff.empty()) - { - std::vector buff(n); - ECRYPT_encrypt_blocks(&m_ctx, (u8*)buf, (u8*)&buff[0], n / ECRYPT_BLOCKLENGTH); - m_underlying_stream.write(&buff[0], n); - }else - { - m_buff.append(buf, n); - size_t encr_count = m_buff.size() - m_buff.size() % ECRYPT_BLOCKLENGTH; - if (!encr_count) - return n; - std::vector buff(encr_count); - ECRYPT_encrypt_blocks(&m_ctx, (u8*)m_buff.data(), (u8*)&buff[0], m_buff.size() / ECRYPT_BLOCKLENGTH); - m_underlying_stream.write(&buff[0], encr_count); - m_buff.erase(0, encr_count); - } - return n; -} - - -void encrypt_chacha_sink::flush() const -{ - if (m_buff.empty()) - return; - - std::vector buff(m_buff.size()); - ECRYPT_encrypt_bytes(&m_ctx, (u8*)m_buff.data(), (u8*)&buff[0], m_buff.size()); - m_underlying_stream.write(&buff[0], m_buff.size()); -} - -encrypt_chacha_sink::~encrypt_chacha_sink() -{ - -} diff --git a/src/common/encryption_sink.h b/src/common/encryption_sink.h deleted file mode 100644 index e10981c6..00000000 --- a/src/common/encryption_sink.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2014-2018 Zano Project -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once - -#include -#include -#include -#include // sink_tag -#include "include_base_utils.h" -#include "crypto/chacha8.h" -#include "crypto/chacha8_stream.h" - - -class encrypt_chacha_sink -{ -public: - typedef char char_type; - typedef boost::iostreams::sink_tag category; - encrypt_chacha_sink(std::ostream &underlyingStream, std::string const &pass, const crypto::chacha8_iv& iv); - std::streamsize write(char_type const * const buf, std::streamsize const n) const; - void flush() const; - ~encrypt_chacha_sink(); -private: - const crypto::chacha8_iv& m_iv; - mutable ECRYPT_ctx m_ctx; - std::ostream &m_underlying_stream; - crypto::chacha8_key m_key; - mutable std::string m_buff; -}; \ No newline at end of file diff --git a/tests/unit_tests/chacha_stream_test.cpp b/tests/unit_tests/chacha_stream_test.cpp index 9e7dc5cf..3c0575dd 100644 --- a/tests/unit_tests/chacha_stream_test.cpp +++ b/tests/unit_tests/chacha_stream_test.cpp @@ -6,10 +6,14 @@ #include #include +#include +#include +#include -#include "common/encryption_sink.h" +#include "common/encryption_filter.h" #include "crypto/crypto.h" + TEST(chacha_stream_test, chacha_stream_test) { LOG_PRINT_L0("chacha_stream_test"); @@ -19,53 +23,94 @@ TEST(chacha_stream_test, chacha_stream_test) { buff[i] = i % 255; } - for (size_t i = 0; i!= 100; i++) - { - std::cout << "Encrypting..." << std::endl; - std::stringstream encrypted; - crypto::chacha8_iv iv = crypto::rand(); +// for (size_t i = 0; i!= 100; i++) +// { +// std::cout << "Encrypting..." << std::endl; +// std::stringstream encrypted; +// crypto::chacha8_iv iv = crypto::rand(); +// +// encrypt_chacha_sink sink(encrypted, "pass", iv); +// +// size_t offset = 0; +// while (offset < buff_size) +// { +// std::streamsize count = std::rand() % 1000; +// if (count + offset > buff_size) +// { +// count = buff_size - offset; +// } +// sink.write(&buff[offset], count); +// +// offset += count; +// } +// sink.flush(); +// std::string buff_encrypted = encrypted.str(); +// +// std::cout << "Decrypting..."; +// std::stringstream decrypted; +// encrypt_chacha_sink sink2(decrypted, "pass", iv); +// offset = 0; +// while (offset < buff_size) +// { +// std::streamsize count = std::rand() % 1000; +// if (count + offset > buff_size) +// { +// count = buff_size - offset; +// } +// sink2.write(&buff_encrypted[offset], count); +// +// offset += count; +// } +// sink2.flush(); +// std::string buff_decrypted = decrypted.str(); +// +// if (buff_decrypted != buff) +// { +// std::cout << "Failed" << std::endl; +// ASSERT_TRUE(false); +// } +// std::cout << "OK" << std::endl; +// } - encrypt_chacha_sink sink(encrypted, "pass", iv); - size_t offset = 0; - while (offset < buff_size) - { - std::streamsize count = std::rand() % 1000; - if (count + offset > buff_size) - { - count = buff_size - offset; - } - sink.write(&buff[offset], count); + 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); + //boost::iostreams::stream outputStream(sink_encrypt); + boost::iostreams::filtering_ostream out; + out.push(encrypt_filter); + out.push(store_data_file); + out << buff; + out.flush(); + store_data_file.close(); - offset += count; - } - sink.flush(); - std::string buff_encrypted = encrypted.str(); - std::cout << "Decrypting..."; - std::stringstream decrypted; - encrypt_chacha_sink sink2(decrypted, "pass", iv); - offset = 0; - while (offset < buff_size) - { - std::streamsize count = std::rand() % 1000; - if (count + offset > buff_size) - { - count = buff_size - offset; - } - sink2.write(&buff_encrypted[offset], count); + 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); - offset += count; - } - sink2.flush(); - std::string buff_decrypted = decrypted.str(); + boost::iostreams::filtering_istream in; + in.push(boost::iostreams::invert(decrypt_filter)); + in.push(data_file); + + //todo: read from stream + auto size = buff_size; + std::string str(size, '\0'); // construct string to stream size + + try { + + in.read(&str[0], size+1); + std::cout << "ddd"; - if (buff_decrypted != buff) - { - std::cout << "Failed" << std::endl; - ASSERT_TRUE(false); - } - std::cout << "OK" << std::endl; } + catch (std::exception& err) + { + std::cout << err.what(); + std::cout << err.what(); + } + + + } \ No newline at end of file