}
/**
- * Encodes a block of file content.
+ * Decodes a block of file content.
*
* @param source the source block
* @param target OUT: the target block<br>
* Can be identical to <code>source</code> (in place replacement)
+ * @param offset decoding start at this content
* @return <code>true</code>: successful<br>
* <code>false</code>: otherwise
*/
bool ReByteScrambler::decodeContent(const QByteArray& source,
- QByteArray& target) {
+ QByteArray& target, int start) {
bool rc = true;
int offset = 0;
target.resize(0);
target.resize(source.length() - offset);
int64_t* trg = reinterpret_cast<int64_t*>(target.data());
int count = (source.length() - offset) / sizeof(int64_t);
- const int64_t* src = reinterpret_cast<const int64_t*>(source.constData() + offset);
+ const int64_t* src = reinterpret_cast<const int64_t*>(source.constData()
+ + offset);
int64_t last = ReRandomizer::m_primes64[0];
- for (int ix = 0; ix < count; ix++) {
+ if (start > 0){
+ memcpy(trg, src, start);
+ start /= sizeof(int64_t);
+ src += offset;
+ trg += offset;
+ }
+ for (int ix = start; ix < count; ix++) {
int64_t last2 = last;
last = *src++;
int64_t rand = m_contentRandom.nextSeed64();
* @param source the source buffer
* @param target OUT: the target buffer.
* May be identical to <code>source</code> (in place processing)
+ * @param start the encryption begins at this index
*/
void ReByteScrambler::encodeContent(const QByteArray& source,
- QByteArray& target) {
+ QByteArray& target, int start) {
target.resize(source.length());
int64_t* trg = reinterpret_cast<int64_t*>(target.data());
int count = source.length() / sizeof(int64_t);
const int64_t* src = reinterpret_cast<const int64_t*>(source.constData());
int64_t last = ReRandomizer::m_primes64[0];
- for (int ix = 0; ix < count; ix++) {
+ if (start > 0){
+ memcpy(trg, src, start);
+ start /= sizeof(int64_t);
+ src += start;
+ trg += start;
+ }
+ for (int ix = start; ix < count; ix++) {
int64_t rand = m_contentRandom.nextSeed64();
IF_TRACE(int64_t last2 = last);
last = *trg++ = *src++ ^ rand ^ last;
public:
ReByteScrambler(ReRandomizer& contentRandom, ReLogger* logger);
public:
- bool decodeContent(const QByteArray& source, QByteArray& target);
- void encodeContent(const QByteArray& source, QByteArray& target);
+ bool decodeContent(const QByteArray& source, QByteArray& target,
+ int offset = 0);
+ void encodeContent(const QByteArray& source, QByteArray& target,
+ int offset = 0);
void initHeader(int metaInfoLength, int markerLength,
const QByteArray& info = ReStringUtils::m_empty);
bool initFromHeader(int metaInfoLength, int markerLength,
testReFileSystem();
}
void allTests() {
- testBase();
testOs();
+ testBase();
testGui();
if (s_allTest) {
testBase();
void init() {
m_hostBase = ReFileUtils::tempDir("cryptfs");
m_sourceBase = ReFileUtils::tempDir("sourcefs");
- m_hostFs = new ReLocalFileSystem(m_hostBase, &m_logger);
+ m_hostFs = new ReLocalFileSystem("/", &m_logger);
+ m_hostFs->setDirectory(m_hostBase);
m_cryptFs = new ReCryptFileSystem(*m_hostFs, m_contentRandom, &m_logger);
}
void destroy(){
virtual void run() {
init();
testWriteRead();
+ destroy();
}
};
void testReCryptFileSystem() {
m_currentNode(),
m_fileBuffer(),
m_entryBuffer(),
+ m_smallBuffer(),
m_blockSize(1024 * 1024),
m_maxFileId(0)
{
{
bool rc = true;
m_list.clear();
- QString fnMetaFile = m_parentFS->directory() + ReCryptFileSystem::NODE_META_DIR;
+ QString fnMetaFile = m_parentFS->host().directory()
+ + ReCryptFileSystem::NODE_META_DIR;
FILE* fp = fopen(fnMetaFile.toUtf8().constData(), "rb");
m_maxFileId = 0;
if (fp != NULL){
int length = node.length();
meta2->m_size += length + (length < 256 ? 0 : 1);
}
- QString fnMetaFile = m_parentFS->directory() + ReCryptFileSystem::NODE_META_DIR;
- FILE* fp = fopen(fnMetaFile.toUtf8().constData(), "rb");
+ QString fnMetaFile = m_parentFS->host().directory()
+ + ReCryptFileSystem::NODE_META_DIR;
+ FILE* fp = fopen(fnMetaFile.toUtf8().constData(), "wb");
if (fp == NULL){
m_logger->logv(LOG_ERROR, LOC_WRITE_META_1, "cannot write (%d): %s",
errno, fnMetaFile.constData());
} else {
m_fileBuffer.append(header);
int ixList = 0;
- while (ixList++ < m_list.length()){
+ while (ixList < m_list.length()){
const ReFileMetaData& file = m_list.at(ixList++);
FileEntry_t trg;
trg.m_created = file.m_created.toMSecsSinceEpoch();
m_fileBuffer.append(node);
if (length >= 256)
m_fileBuffer.append('\0');
- if (m_fileBuffer.length() >= m_blockSize || ixList >= m_list.length()){
- m_entryBuffer.resize(0);
- if (m_fileBuffer.length() > m_blockSize){
- m_entryBuffer = m_fileBuffer.mid(m_blockSize);
- m_fileBuffer.resize(m_blockSize);
+ int blockLength = m_fileBuffer.length();
+ bool lastBlock = ixList >= m_list.length();
+ if (lastBlock ||blockLength >= m_blockSize - 512){
+ if (! lastBlock && blockLength % sizeof(int64_t) != 0){
+ int newLength = blockLength - blockLength % sizeof(int64_t);
+ m_smallBuffer = m_fileBuffer.mid(newLength);
+ m_fileBuffer.resize(newLength);
}
- encodeContent(m_fileBuffer, m_fileBuffer);
+ int offset = ixList <= 1 ? META_DIR_HEADER_LENGTH : 0;
+ encodeContent(m_fileBuffer, m_fileBuffer, offset);
int nWritten = fwrite(m_fileBuffer.constData(), 1,
m_fileBuffer.length(), fp);
if (nWritten != m_fileBuffer.length()){
"write error (%d): %s [%d/%d]", errno,
nWritten, m_fileBuffer.length());
}
+ m_fileBuffer.resize(0);
+ if (! lastBlock && blockLength % sizeof(int64_t) != 0)
+ m_fileBuffer.append(m_smallBuffer);
}
}
+ fclose(fp);
}
return rc;
}
QString m_currentNode;
QByteArray m_fileBuffer;
QByteArray m_entryBuffer;
+ QByteArray m_smallBuffer;
int m_blockSize;
int m_maxFileId;
};