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;
{
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;
}
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();
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){
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;
}
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();
{
if (doReset){
m_contentRandom.reset();
- m_contentRandom.modifySeed(m_salt);
+ m_contentRandom.modifySeed(m_salt.m_int);
}
return m_contentRandom;
}
/**
* 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;
* 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;
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);
+}