]> gitweb.hamatoma.de Git - reqt/commitdiff
refactoring ReByteScrambler
authorhama <hama@siduction.net>
Sat, 14 Nov 2015 00:23:37 +0000 (01:23 +0100)
committerhama <hama@siduction.net>
Sat, 14 Nov 2015 00:23:37 +0000 (01:23 +0100)
base/ReRandomizer.cpp
base/ReRandomizer.hpp
cunit/cuReRandomizer.cpp
os/ReCryptFileSystem.cpp

index 9ac4f6f8d4cb71b52f08bbe1d466f085f394dac9..0a1503b4986fd14570e58d0506106ddc83c81ac3 100644 (file)
@@ -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<uint8_t*>(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<const uint8_t*>(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<const char*>(src), needed);
                        length -= needed;
                        src += needed;
-                       memcpy(&data, m_rest.constData(), sizeof data);
-                       CalcNextHash(data);
+                       data.fromBytes(reinterpret_cast<const uint8_t*>(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<seed_t*>(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<uint8_t*>(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                                     <code>true</code>: 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<const int64_t*>(header->constData());
-               m_contentRandom.reset();
-               m_contentRandom.modifySeed(m_salt);
-               QByteArray marker;
-               marker.append(reinterpret_cast<const char*>(header->constData()+ sizeof(int64_t)),
-                                                                                                       markerLength);
-               QByteArray marker2;
+               m_salt.fromBytes(reinterpret_cast<const uint8_t*>(header->constData()));
+               randomReset();
+               QByteArray expectedMarker;
+               if (markerLength > 0)
+                       m_contentRandom.nextString(markerLength, markerLength, expectedMarker);
+               if (encryptedFrom < m_header.length()){
+                       uint8_t* start = reinterpret_cast<uint8_t*>(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<const char*>(
+                                       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<const char*>(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:
- * <pre>random (8 byte)
- * marker (m_markerLength byte)
- * reserved (reservedLength byte)
+ * <pre>random (8 bytes)
+ * unencrypted area (unencryptedSpace bytes)
+ * marker (m_markerLength bytes)
+ * reserved (reservedLength bytes)
  * </pre>
- *
- * @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<int64_t*>(m_header.data()) = m_salt;
+       m_salt.toBytes(reinterpret_cast<uint8_t*>(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<char*>(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<uint8_t*>(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);
+}
index 24926c71740599855443cbcb9e6207257955a7a0..77e977769630fb180f1ca5d83a0a15364c178a4c 100644 (file)
@@ -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_ */
index baf7718017f26ca9b93888cde265e08a75fd4be8..f29cd40b6a1e9a72baecca6350f077b59faf18eb 100644 (file)
@@ -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();
index 5e4e44ae1ec45aa52b1eddf0398c0371d6de645e..eaaa9b98e36d837c3d3ebd9c3679ecad8fe21c78 100644 (file)
@@ -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<const MetaInfo_t*>(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();