From a50ba8b8b6b4528b3d8b6c70ae31342396c4b492 Mon Sep 17 00:00:00 2001 From: hama Date: Sat, 14 Nov 2015 01:23:37 +0100 Subject: [PATCH] refactoring ReByteScrambler --- base/ReRandomizer.cpp | 150 ++++++++++++++++++++++----------------- base/ReRandomizer.hpp | 13 ++-- cunit/cuReRandomizer.cpp | 6 +- os/ReCryptFileSystem.cpp | 4 +- 4 files changed, 96 insertions(+), 77 deletions(-) diff --git a/base/ReRandomizer.cpp b/base/ReRandomizer.cpp index 9ac4f6f..0a1503b 100644 --- a/base/ReRandomizer.cpp +++ b/base/ReRandomizer.cpp @@ -196,9 +196,10 @@ int64_t ReHmHash64::digestAsInt() int64_t rc; if (m_rest.length() > 0){ - rc = 0; - memcpy(&rc, m_rest.constData(), m_rest.length()); - CalcNextHash(rc); + int64_converter_t data; + data.m_int = 0; + memcpy(data.m_bytes, m_rest.constData(), m_rest.length()); + CalcNextHash(data.m_int); } CalcNextHash(m_sumLength); rc = m_hash; @@ -217,8 +218,9 @@ QByteArray ReHmHash64::digest() { QByteArray rc; rc.resize(sizeof m_hash); - int64_t value = digestAsInt(); - memcpy(rc.data(), &value, sizeof m_hash); + int64_converter_t data; + data.m_int = digestAsInt(); + data.toBytes(reinterpret_cast(rc.data())); return rc; } @@ -242,7 +244,7 @@ void ReHmHash64::reset(){ void ReHmHash64::update(const void* source, size_t length) { const uint8_t* src = reinterpret_cast(source); - int64_t data; + int64_converter_t data; m_sumLength += length; if (m_rest.length() > 0){ size_t needed = sizeof m_hash - m_rest.length(); @@ -253,15 +255,15 @@ void ReHmHash64::update(const void* source, size_t length) m_rest.append(reinterpret_cast(src), needed); length -= needed; src += needed; - memcpy(&data, m_rest.constData(), sizeof data); - CalcNextHash(data); + data.fromBytes(reinterpret_cast(m_rest.constData())); + CalcNextHash(data.m_int); m_rest.clear(); } } for (int ix = length / sizeof m_hash - 1; ix >= 0; ix--){ - memcpy(&data, src, sizeof data); - src += sizeof data; - CalcNextHash(data); + data.fromBytes(src); + src += sizeof m_hash; + CalcNextHash(data.m_int); } int rest = length % sizeof m_hash; if (rest > 0){ @@ -423,9 +425,14 @@ QByteArray& ReRandomizer::nextData(int minLength, int maxLength, seed_t* ptr = reinterpret_cast(buffer.data()); for (int ix = len / sizeof data - 1; ix >= 0; ix--) *ptr = nextSeed64(); - if (len % sizeof data != 0){ + int rest = len % sizeof data; + if (rest != 0){ data = nextSeed64(); - memcpy(ptr, &data, len % sizeof data); + uint8_t* ptr2 = reinterpret_cast(ptr); + while(rest-- > 0){ + *ptr2++ = data; + data >>= 8; + } } return buffer; } @@ -1047,8 +1054,9 @@ ReByteScrambler::ReByteScrambler(ReRandomizer& contentRandom, ReLogger* logger) m_buffer(), m_header(), m_logger(logger), - m_salt(0) + m_salt() { + m_salt.m_int = 0; m_contentRandom.saveSeed(m_contentSeed); m_buffer.reserve(256); m_realRandom.nearTrueRandom(); @@ -1064,7 +1072,7 @@ ReRandomizer& ReByteScrambler::contentRandom(bool doReset) { if (doReset){ m_contentRandom.reset(); - m_contentRandom.modifySeed(m_salt); + m_contentRandom.modifySeed(m_salt.m_int); } return m_contentRandom; } @@ -1072,57 +1080,61 @@ ReRandomizer& ReByteScrambler::contentRandom(bool doReset) /** * Initializes the scrambler from a header. * - * @param metaInfoLength the length of the "reserved area" * @param markerLength length of a mark to ensure header's integrity + * @param infoLength the length of the "reserved area" * @param encryptedFrom the first index from which data are encrypted. * the first possible index is behind the marker - * @param header the header with the initializing info. If NULL the - * internal header will be used + * @param header OUT: the header with the initializing info. If NULL the + * internal header will be used. + * Otherwise the parts of the header will be decrypted * @param info OUT: the reserved area in the header * @return true: success */ -bool ReByteScrambler::initFromHeader(int metaInfoLength, int markerLength, - int encryptedFrom, const QByteArray* header, QByteArray& info) +bool ReByteScrambler::initFromHeader(int reservedLength, int markerLength, + int infoLength, int encryptedFrom, QByteArray* header, + QByteArray& info) { TRACE("initFromHeader():\n"); - encryptedFrom = max(encryptedFrom, encryptedFrom < sizeof(int64_t) + markerLength); + encryptedFrom = max(encryptedFrom, encryptedFrom < (int) sizeof(int64_t) + + reservedLength + markerLength); bool rc = true; if (header == NULL) header = &m_header; - int headerLength = sizeof(int64_t) + markerLength + metaInfoLength; + int headerLength = sizeof(int64_t) + reservedLength + markerLength + infoLength; if (header->length() < headerLength ){ m_logger->logv(LOG_ERROR, LOC_DECODE_CONTENT_1, "header length too small: %d/%d", header->length(), headerLength); rc = false; } else { - m_salt = * reinterpret_cast(header->constData()); - m_contentRandom.reset(); - m_contentRandom.modifySeed(m_salt); - QByteArray marker; - marker.append(reinterpret_cast(header->constData()+ sizeof(int64_t)), - markerLength); - QByteArray marker2; + m_salt.fromBytes(reinterpret_cast(header->constData())); + randomReset(); + QByteArray expectedMarker; + if (markerLength > 0) + m_contentRandom.nextString(markerLength, markerLength, expectedMarker); + if (encryptedFrom < m_header.length()){ + uint8_t* start = reinterpret_cast(header->data()) + encryptedFrom; + m_contentRandom.codec(start, start, header->length() - encryptedFrom); + } if (markerLength > 0){ - m_contentRandom.nextString(markerLength, markerLength, marker2); - if (marker != marker2){ - m_logger->logv(LOG_ERROR, LOC_DECODE_CONTENT_2, "invalid marker: %s / %s", - ReStringUtils::hexDump(marker, markerLength, markerLength).constData(), - ReStringUtils::hexDump(marker2, markerLength, markerLength).constData()); + QByteArray marker; + marker.append(reinterpret_cast( + header->constData()+ sizeof(int64_t) + reservedLength), + markerLength); + if (marker != expectedMarker){ + m_logger->logv(LOG_ERROR, LOC_DECODE_CONTENT_2, + "invalid marker: %s / %s", + ReStringUtils::hexDump(marker, markerLength, + markerLength).constData(), + ReStringUtils::hexDump(expectedMarker, + markerLength, markerLength).constData()); rc = false; } } - char last = 0x47; - const char* src = reinterpret_cast(header->data() - + sizeof (int64_t) + markerLength); - int length = *src++; TRACE1("info: Length: %d\n", length); info.resize(0); - for (int ix = 0; ix < length; ix++){ - char last2 = last; - last = *src++; - char rand = m_contentRandom.nextChar(); - info.append(last ^ rand ^ last2); - } + if (infoLength > 0) + info = header->mid(sizeof(int64_t) + reservedLength + markerLength, + infoLength); } IF_TRACE(m_contentRandom.dump()); return rc; @@ -1132,35 +1144,37 @@ bool ReByteScrambler::initFromHeader(int metaInfoLength, int markerLength, * Initializes the scrambler header. * * Format of the header: - *
random (8 byte)
- * marker (m_markerLength byte)
- * reserved (reservedLength byte)
+ * 
random (8 bytes)
+ * unencrypted area (unencryptedSpace bytes)
+ * marker (m_markerLength bytes)
+ * reserved (reservedLength bytes)
  * 
- * - * @param metaInfoLength the length of the "reserved area" + * @param reservedLength the length of the not encrypted area behind the random * @param markerLength length of a mark to ensure header's integrity + * @param infoLength the length of the "reserved area" * @param encryptedFrom the first index from which data are encrypted. * the first possible index is behind the marker * @param info the content of the "reserved area". If too few space * the content will be cut */ -void ReByteScrambler::initHeader(int metaInfoLength, int markerLength, - int encryptedFrom, const QByteArray& info) +void ReByteScrambler::initHeader(int reservedLength, int markerLength, + int infoLength, int encryptedFrom, const QByteArray& info) { TRACE("initHeader():\n"); - encryptedFrom = max(encryptedFrom, encryptedFrom < sizeof(int64_t) + markerLength); - m_salt = m_realRandom.nextSeed64(); + encryptedFrom = max(encryptedFrom, encryptedFrom < (int) sizeof(int64_t) + + reservedLength + markerLength); + m_salt.m_int = m_realRandom.nextSeed64(); m_contentRandom.reset(); - m_contentRandom.modifySeed(m_salt); - int headerLength = sizeof(int64_t) + markerLength + metaInfoLength; + m_contentRandom.modifySeed(m_salt.m_int); + int headerLength = sizeof(int64_t) + reservedLength + markerLength + infoLength; m_header.fill(' ', headerLength); - * reinterpret_cast(m_header.data()) = m_salt; + m_salt.toBytes(reinterpret_cast(m_header.data())); if (markerLength > 0){ m_buffer.resize(0); m_contentRandom.nextString(markerLength, markerLength, m_buffer); - memcpy(m_header.data() + sizeof(int64_t), m_buffer, markerLength); + memcpy(m_header.data() + sizeof(int64_t) + reservedLength, + m_buffer, markerLength); } - char last = 0x47; char* trg; if (info.length() > 0){ int offset = sizeof(int64_t) + markerLength; @@ -1168,15 +1182,19 @@ void ReByteScrambler::initHeader(int metaInfoLength, int markerLength, memcpy(trg, info, min(m_header.length() - offset, info.length())); } if (encryptedFrom < m_header.length()){ - char* trg = reinterpret_cast(m_header.data() + encryptedFrom); - int infoLength = min(info.length(), metaInfoLength - 1); - TRACE2("info: length: %d reserved: %d\n", infoLength, metaInfoLength); - *trg++ = infoLength; - for (int ix = 0; ix < infoLength && ix < metaInfoLength; ix++){ - last = *trg++ = m_contentRandom.nextChar() ^ info.at(ix) ^ last; - } + randomReset(); + uint8_t* start = reinterpret_cast(m_header.data() + encryptedFrom); + m_contentRandom.codec(start, start, m_header.length() - encryptedFrom); } - TRACE_IT(("random: %016lx marker: %s\n", m_salt, + TRACE_IT(("random: %016lx marker: %s\n", m_salt.m_int, m_buffer.constData())); IF_TRACE(m_contentRandom.dump()); } + +/** + * Resets the pseudo random generator to the scrambler specific state (salt). + */ +void ReByteScrambler::randomReset() +{ + m_contentRandom.modifySeed(m_salt.m_int); +} diff --git a/base/ReRandomizer.hpp b/base/ReRandomizer.hpp index 24926c7..77e9777 100644 --- a/base/ReRandomizer.hpp +++ b/base/ReRandomizer.hpp @@ -335,11 +335,12 @@ public: ReByteScrambler(ReRandomizer& contentRandom, ReLogger* logger); public: ReRandomizer& contentRandom(bool doReset); - bool initFromHeader(int metaInfoLength, int markerLength, int encryptFrom, - const QByteArray* header, QByteArray& info); - void initHeader(int metaInfoLength, int markerLength, int encryptFrom, - const QByteArray& info = ReStringUtils::m_empty); - + bool initFromHeader(int reservedLength, int markerLength, + int infoLength, int encryptedFrom, QByteArray* header, + QByteArray& info); + void initHeader(int reservedLength, int markerLength, int infoLength, + int encryptFrom, const QByteArray& info = ReStringUtils::m_empty); + void randomReset(); protected: ReRandomizer& m_contentRandom; ReKISSRandomizer m_realRandom; @@ -347,7 +348,7 @@ protected: QByteArray m_buffer; QByteArray m_header; ReLogger* m_logger; - ReRandomizer::seed_t m_salt; + int64_converter_t m_salt; }; #endif /* RANDOMIZER_H_ */ diff --git a/cunit/cuReRandomizer.cpp b/cunit/cuReRandomizer.cpp index baf7718..f29cd40 100644 --- a/cunit/cuReRandomizer.cpp +++ b/cunit/cuReRandomizer.cpp @@ -169,10 +169,10 @@ public: rand.nearTrueRandom(); QByteArray info; rand.nextString(10, 20, info); - scrambler.initHeader(metaInfoLength, markerLength, 0, info); + scrambler.initHeader(0, markerLength, metaInfoLength, 0, info); scrambler.contentRandom(true).codec(trg, src); QByteArray info2; - scrambler.initFromHeader(metaInfoLength, markerLength, 0, NULL, info2); + scrambler.initFromHeader(0, markerLength, metaInfoLength, 0, NULL, info2); scrambler.contentRandom(true).codec(trg2, trg); checkEqu(src, trg2); checkT(info.startsWith(info2)); @@ -438,7 +438,7 @@ public: testRealRandom(); testShuffle(); special(); - //testContentEncoding(); + testContentEncoding(); testModifySeed(); testTextToSeed(); testWrite1m(); diff --git a/os/ReCryptFileSystem.cpp b/os/ReCryptFileSystem.cpp index 5e4e44a..eaaa9b9 100644 --- a/os/ReCryptFileSystem.cpp +++ b/os/ReCryptFileSystem.cpp @@ -450,7 +450,7 @@ bool ReCryptDirectory::readMetaFile() fnMetaFile.toUtf8().constData(), nRead, META_DIR_HEADER_LENGTH); } else { QByteArray info; - rc = initFromHeader(META_INFO_LENGTH, MARKER_LENGTH, 0, &header, info); + rc = initFromHeader(0, MARKER_LENGTH, META_INFO_LENGTH, 0, &header, info); if (rc){ const MetaInfo_t* meta = reinterpret_cast(info.constData()); if (meta->m_countFiles > 0){ @@ -499,7 +499,7 @@ bool ReCryptDirectory::writeMetaFile() int length = it->m_node.toUtf8().length(); meta2->m_size += length + (length < 256 ? 0 : 1); } - initHeader(META_INFO_LENGTH, MARKER_LENGTH, 0, meta); + initHeader(0, MARKER_LENGTH, META_INFO_LENGTH, 0, meta); QByteArray node; for (it = m_list.cbegin(); it != m_list.cend(); ++it){ node = it->m_node.toUtf8(); -- 2.39.5