From: Maxim Mamontov Date: Sat, 21 Jun 2014 20:39:36 +0000 (+0300) Subject: Added stream encryption/decryption. X-Git-Url: https://git.stg.codes/stg.git/commitdiff_plain/d4c4fa8efc14b0b5e9bbca41af0e24e652a28d11?ds=inline Added stream encryption/decryption. --- diff --git a/stglibs/crypto.lib/bfstream.cpp b/stglibs/crypto.lib/bfstream.cpp new file mode 100644 index 00000000..4f376c5d --- /dev/null +++ b/stglibs/crypto.lib/bfstream.cpp @@ -0,0 +1,122 @@ +#include "stg/bfstream.h" + +#include "stg/blowfish.h" + +#include + +namespace +{ + +#ifndef BFSTREAM_BUF_SIZE +const size_t BUFFER_SIZE = 1024; +#else +const size_t BUFFER_SIZE = BFSTREAM_BUF_SIZE; +#endif + +class COMMON +{ + public: + typedef void (* CALLBACK)(const void * block, size_t size, void * data); + typedef void (* PROC)(void * dest, const void * source, size_t length, const BLOWFISH_CTX * ctx); + + COMMON(const std::string & key, CALLBACK callback, void * data, PROC proc) + : m_ptr(m_buffer), + m_callback(callback), + m_data(data), + m_proc(proc) + { + InitContext(key.c_str(), key.length(), &m_ctx); + } + + void Put(const void * data, size_t size, bool last) + { + size_t dataSize = m_ptr - m_buffer; + if (dataSize + size > sizeof(m_buffer)) + { + memcpy(m_ptr, data, sizeof(m_buffer) - dataSize); // Fill buffer + size -= sizeof(m_buffer) - dataSize; // Adjust size + data += sizeof(m_buffer) - dataSize; // Adjust data pointer + m_proc(m_buffer, m_buffer, sizeof(m_buffer), &m_ctx); // Process + m_callback(m_buffer, sizeof(m_buffer), m_data); // Consume + m_ptr = m_buffer; + } + memcpy(m_ptr, data, size); + m_ptr += size; + m_tryConsume(last); + } + + private: + char m_buffer[BUFFER_SIZE]; + char * m_ptr; + CALLBACK m_callback; + void * m_data; + BLOWFISH_CTX m_ctx; + PROC m_proc; + + void m_tryConsume(bool last) + { + size_t dataSize = (m_ptr - m_buffer) & ~7; + size_t remainder = m_ptr - m_buffer - dataSize; + if (last && remainder > 0) + { + dataSize += 8; + remainder = 0; + } + if (dataSize == 0) + return; + m_proc(m_buffer, m_buffer, dataSize, &m_ctx); + m_callback(m_buffer, dataSize, m_data); + if (remainder > 0) + memmove(m_buffer, m_buffer + dataSize, remainder); + m_ptr = m_buffer + remainder; + } +}; + +} // namespace anonymous + +using STG::ENCRYPT_STREAM; +using STG::DECRYPT_STREAM; + +class ENCRYPT_STREAM::IMPL : public COMMON +{ + public: + IMPL(const std::string & key, CALLBACK callback, void * data) + : COMMON(key, callback, data, EncryptString) + {} +}; + +class DECRYPT_STREAM::IMPL : public COMMON +{ + public: + IMPL(const std::string & key, CALLBACK callback, void * data) + : COMMON(key, callback, data, DecryptString) + {} +}; + +ENCRYPT_STREAM::ENCRYPT_STREAM(const std::string & key, CALLBACK callback, void * data) + : m_impl(new IMPL(key, callback, data)) +{} + +ENCRYPT_STREAM::~ENCRYPT_STREAM() +{ +delete m_impl; +} + +void ENCRYPT_STREAM::Put(const void * data, size_t size, bool last) +{ +m_impl->Put(data, size, last); +} + +DECRYPT_STREAM::DECRYPT_STREAM(const std::string & key, CALLBACK callback, void * data) + : m_impl(new IMPL(key, callback, data)) +{} + +DECRYPT_STREAM::~DECRYPT_STREAM() +{ +delete m_impl; +} + +void DECRYPT_STREAM::Put(const void * data, size_t size, bool last) +{ +m_impl->Put(data, size, last); +} diff --git a/stglibs/crypto.lib/include/stg/bfstream.h b/stglibs/crypto.lib/include/stg/bfstream.h new file mode 100644 index 00000000..41b44330 --- /dev/null +++ b/stglibs/crypto.lib/include/stg/bfstream.h @@ -0,0 +1,42 @@ +#ifndef __STG_STGLIBS_BF_STREAM_H__ +#define __STG_STGLIBS_BF_STREAM_H__ + +#include +#include // size_t + +namespace STG +{ + +class ENCRYPT_STREAM +{ + public: + typedef void (* CALLBACK)(const void * block, size_t size, void * data); + + ENCRYPT_STREAM(const std::string & key, CALLBACK callback, void * data); + ~ENCRYPT_STREAM(); + void Put(const void * data, size_t size, bool last = false); + + private: + class IMPL; + + IMPL * m_impl; +}; + +class DECRYPT_STREAM +{ + public: + typedef void (* CALLBACK)(const void * block, size_t size, void * data); + + DECRYPT_STREAM(const std::string & key, CALLBACK callback, void * data); + ~DECRYPT_STREAM(); + void Put(const void * data, size_t size, bool last = false); + + private: + class IMPL; + + IMPL * m_impl; +}; + +} // namespace STG + +#endif