diff --git a/src/crypto/SymmetricCipher.cpp b/src/crypto/SymmetricCipher.cpp index 95f91dc63..0e50dd4ad 100644 --- a/src/crypto/SymmetricCipher.cpp +++ b/src/crypto/SymmetricCipher.cpp @@ -49,16 +49,6 @@ SymmetricCipherBackend* SymmetricCipher::createBackend(SymmetricCipher::Algorith } } -QByteArray SymmetricCipher::process(const QByteArray& data) -{ - return m_backend->process(data); -} - -void SymmetricCipher::processInPlace(QByteArray& data) -{ - m_backend->processInPlace(data); -} - void SymmetricCipher::reset() { m_backend->reset(); diff --git a/src/crypto/SymmetricCipher.h b/src/crypto/SymmetricCipher.h index 8a24f3172..c5a6f7ece 100644 --- a/src/crypto/SymmetricCipher.h +++ b/src/crypto/SymmetricCipher.h @@ -21,7 +21,7 @@ #include #include -class SymmetricCipherBackend; +#include "crypto/SymmetricCipherBackend.h" class SymmetricCipher { @@ -49,8 +49,18 @@ public: SymmetricCipher::Direction direction, const QByteArray& key, const QByteArray& iv); ~SymmetricCipher(); - QByteArray process(const QByteArray& data); - void processInPlace(QByteArray& data); + inline QByteArray process(const QByteArray& data) { + return m_backend->process(data); + } + + inline void processInPlace(QByteArray& data) { + m_backend->processInPlace(data); + } + + inline void processInPlace(QByteArray& data, int rounds) { + Q_ASSERT(rounds > 0); + m_backend->processInPlace(data, rounds); + } void reset(); int blockSize() const; diff --git a/src/crypto/SymmetricCipherBackend.h b/src/crypto/SymmetricCipherBackend.h index a46052987..64a545003 100644 --- a/src/crypto/SymmetricCipherBackend.h +++ b/src/crypto/SymmetricCipherBackend.h @@ -18,7 +18,7 @@ #ifndef KEEPASSX_SYMMETRICCIPHERBACKEND_H #define KEEPASSX_SYMMETRICCIPHERBACKEND_H -#include "crypto/SymmetricCipher.h" +#include class SymmetricCipherBackend { @@ -30,6 +30,7 @@ public: virtual QByteArray process(const QByteArray& data) = 0; virtual void processInPlace(QByteArray& data) = 0; + virtual void processInPlace(QByteArray& data, int rounds) = 0; virtual void reset() = 0; virtual int blockSize() const = 0; diff --git a/src/crypto/SymmetricCipherGcrypt.cpp b/src/crypto/SymmetricCipherGcrypt.cpp index fb501a9e0..ba5c1455b 100644 --- a/src/crypto/SymmetricCipherGcrypt.cpp +++ b/src/crypto/SymmetricCipherGcrypt.cpp @@ -113,6 +113,26 @@ void SymmetricCipherGcrypt::processInPlace(QByteArray& data) Q_ASSERT(error == 0); } +void SymmetricCipherGcrypt::processInPlace(QByteArray& data, int rounds) +{ + // TODO check block size + + gcry_error_t error; + + if (m_direction == SymmetricCipher::Decrypt) { + for (int i = 0; i != rounds; ++i) { + error = gcry_cipher_decrypt(m_ctx, data.data(), data.size(), 0, 0); + Q_ASSERT(error == 0); + } + } + else { + for (int i = 0; i != rounds; ++i) { + error = gcry_cipher_encrypt(m_ctx, data.data(), data.size(), 0, 0); + Q_ASSERT(error == 0); + } + } +} + void SymmetricCipherGcrypt::reset() { gcry_error_t error; diff --git a/src/crypto/SymmetricCipherGcrypt.h b/src/crypto/SymmetricCipherGcrypt.h index d8a871dd7..ccf84ada6 100644 --- a/src/crypto/SymmetricCipherGcrypt.h +++ b/src/crypto/SymmetricCipherGcrypt.h @@ -20,6 +20,7 @@ #include +#include "crypto/SymmetricCipher.h" #include "crypto/SymmetricCipherBackend.h" class SymmetricCipherGcrypt : public SymmetricCipherBackend @@ -34,6 +35,7 @@ public: QByteArray process(const QByteArray& data); void processInPlace(QByteArray& data); + void processInPlace(QByteArray& data, int rounds); void reset(); int blockSize() const; diff --git a/src/crypto/SymmetricCipherSalsa20.cpp b/src/crypto/SymmetricCipherSalsa20.cpp index 53af8a8b9..53aa18baf 100644 --- a/src/crypto/SymmetricCipherSalsa20.cpp +++ b/src/crypto/SymmetricCipherSalsa20.cpp @@ -74,6 +74,16 @@ void SymmetricCipherSalsa20::processInPlace(QByteArray& data) reinterpret_cast(data.data()), data.size()); } +void SymmetricCipherSalsa20::processInPlace(QByteArray& data, int rounds) +{ + Q_ASSERT((data.size() < blockSize()) || ((data.size() % blockSize()) == 0)); + + for (int i = 0; i != rounds; ++i) { + ECRYPT_encrypt_bytes(&m_ctx, reinterpret_cast(data.constData()), + reinterpret_cast(data.data()), data.size()); + } +} + void SymmetricCipherSalsa20::reset() { ECRYPT_ivsetup(&m_ctx, reinterpret_cast(m_iv.constData())); diff --git a/src/crypto/SymmetricCipherSalsa20.h b/src/crypto/SymmetricCipherSalsa20.h index b2366e45b..d0ba39849 100644 --- a/src/crypto/SymmetricCipherSalsa20.h +++ b/src/crypto/SymmetricCipherSalsa20.h @@ -18,6 +18,7 @@ #ifndef KEEPASSX_SYMMETRICCIPHERSALSA20_H #define KEEPASSX_SYMMETRICCIPHERSALSA20_H +#include "crypto/SymmetricCipher.h" #include "crypto/SymmetricCipherBackend.h" #include "crypto/salsa20/ecrypt-sync.h" @@ -36,6 +37,7 @@ public: QByteArray process(const QByteArray& data); void processInPlace(QByteArray& data); + void processInPlace(QByteArray& data, int rounds); void reset(); int blockSize() const; diff --git a/src/keys/CompositeKey.cpp b/src/keys/CompositeKey.cpp index 922674d7c..0c7c43537 100644 --- a/src/keys/CompositeKey.cpp +++ b/src/keys/CompositeKey.cpp @@ -94,9 +94,7 @@ QByteArray CompositeKey::transformKeyRaw(const QByteArray& key, const QByteArray QByteArray result = key; - for (int i = 0; i < rounds; i++) { - cipher.processInPlace(result); - } + cipher.processInPlace(result, rounds); return result; }