From 4727b92a16642c50674894067f7f3dc2aaebb709 Mon Sep 17 00:00:00 2001 From: Janek Bevendorff Date: Fri, 20 Nov 2020 21:49:56 +0100 Subject: [PATCH] Add Argon2id KDF (backport of #5726) --- src/cli/Import.cpp | 2 +- src/crypto/kdf/Argon2Kdf.cpp | 32 ++++++++--- src/crypto/kdf/Argon2Kdf.h | 12 ++++- src/format/KeePass2.cpp | 13 +++-- src/format/KeePass2.h | 3 +- src/format/OpVaultReader.cpp | 2 +- .../DatabaseSettingsWidgetEncryption.cpp | 31 ++++++----- tests/TestKdbx4.cpp | 54 ++++++++++--------- tests/TestKeePass2Format.cpp | 2 +- tests/gui/TestGui.cpp | 2 +- 10 files changed, 96 insertions(+), 57 deletions(-) diff --git a/src/cli/Import.cpp b/src/cli/Import.cpp index 930158988a..148ee5285b 100644 --- a/src/cli/Import.cpp +++ b/src/cli/Import.cpp @@ -83,7 +83,7 @@ int Import::execute(const QStringList& arguments) QString errorMessage; Database db; - db.setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2)); + db.setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D)); db.setKey(key); if (!db.import(xmlExportPath, &errorMessage)) { diff --git a/src/crypto/kdf/Argon2Kdf.cpp b/src/crypto/kdf/Argon2Kdf.cpp index 31995fdd09..cc23def839 100644 --- a/src/crypto/kdf/Argon2Kdf.cpp +++ b/src/crypto/kdf/Argon2Kdf.cpp @@ -29,8 +29,9 @@ * a 256-bit salt is generated each time the database is saved, the tag length is 256 bits, no secret key * or associated data. KeePass uses the latest version of Argon2, v1.3. */ -Argon2Kdf::Argon2Kdf() - : Kdf::Kdf(KeePass2::KDF_ARGON2) +Argon2Kdf::Argon2Kdf(Type type) + : Kdf::Kdf(KeePass2::KDF_ARGON2D) + , m_type(type) , m_version(0x13) , m_memory(1 << 16) , m_parallelism(static_cast(QThread::idealThreadCount())) @@ -54,6 +55,16 @@ bool Argon2Kdf::setVersion(quint32 version) return false; } +Argon2Kdf::Type Argon2Kdf::type() const +{ + return m_type; +} + +void Argon2Kdf::setType(Type type) +{ + m_type = type; +} + quint64 Argon2Kdf::memory() const { return m_memory; @@ -133,7 +144,11 @@ bool Argon2Kdf::processParameters(const QVariantMap& p) QVariantMap Argon2Kdf::writeParameters() { QVariantMap p; - p.insert(KeePass2::KDFPARAM_UUID, KeePass2::KDF_ARGON2.toRfc4122()); + if (type() == Type::Argon2d) { + p.insert(KeePass2::KDFPARAM_UUID, KeePass2::KDF_ARGON2D.toRfc4122()); + } else { + p.insert(KeePass2::KDFPARAM_UUID, KeePass2::KDF_ARGON2ID.toRfc4122()); + } p.insert(KeePass2::KDFPARAM_ARGON2_VERSION, version()); p.insert(KeePass2::KDFPARAM_ARGON2_PARALLELISM, parallelism()); p.insert(KeePass2::KDFPARAM_ARGON2_MEMORY, memory() * 1024); @@ -158,18 +173,20 @@ bool Argon2Kdf::transform(const QByteArray& raw, QByteArray& result) const { result.clear(); result.resize(32); - return transformKeyRaw(raw, seed(), version(), rounds(), memory(), parallelism(), result); + return transformKeyRaw(raw, seed(), version(), type(), rounds(), memory(), parallelism(), result); } bool Argon2Kdf::transformKeyRaw(const QByteArray& key, const QByteArray& seed, quint32 version, + Type type, quint32 rounds, quint64 memory, quint32 parallelism, QByteArray& result) { // Time Cost, Mem Cost, Threads/Lanes, Password, length, Salt, length, out, length + int rc = argon2_hash(rounds, memory, parallelism, @@ -181,7 +198,7 @@ bool Argon2Kdf::transformKeyRaw(const QByteArray& key, result.size(), nullptr, 0, - Argon2_d, + type == Type::Argon2d ? Argon2_d : Argon2_id, version); if (rc != ARGON2_OK) { qWarning("Argon2 error: %s", argon2_error_message(rc)); @@ -205,7 +222,7 @@ int Argon2Kdf::benchmarkImpl(int msec) const timer.start(); int rounds = 4; - if (transformKeyRaw(key, seed, version(), rounds, memory(), parallelism(), key)) { + if (transformKeyRaw(key, seed, version(), type(), rounds, memory(), parallelism(), key)) { return static_cast(rounds * (static_cast(msec) / timer.elapsed())); } @@ -214,5 +231,6 @@ int Argon2Kdf::benchmarkImpl(int msec) const QString Argon2Kdf::toString() const { - return QObject::tr("Argon2 (%1 rounds, %2 KB)").arg(QString::number(rounds()), QString::number(memory())); + return QObject::tr("Argon2%1 (%2 rounds, %3 KB)") + .arg(type() == Type::Argon2d ? "d" : "id", QString::number(rounds()), QString::number(memory())); } diff --git a/src/crypto/kdf/Argon2Kdf.h b/src/crypto/kdf/Argon2Kdf.h index 6a16ee96e5..b3a8c49b3c 100644 --- a/src/crypto/kdf/Argon2Kdf.h +++ b/src/crypto/kdf/Argon2Kdf.h @@ -23,7 +23,13 @@ class Argon2Kdf : public Kdf { public: - Argon2Kdf(); + enum class Type + { + Argon2d, + Argon2id + }; + + Argon2Kdf(Type type); bool processParameters(const QVariantMap& p) override; QVariantMap writeParameters() override; @@ -32,6 +38,8 @@ class Argon2Kdf : public Kdf quint32 version() const; bool setVersion(quint32 version); + Type type() const; + void setType(Type type); quint64 memory() const; bool setMemory(quint64 kibibytes); quint32 parallelism() const; @@ -41,6 +49,7 @@ class Argon2Kdf : public Kdf protected: int benchmarkImpl(int msec) const override; + Type m_type; quint32 m_version; quint64 m_memory; quint32 m_parallelism; @@ -49,6 +58,7 @@ class Argon2Kdf : public Kdf Q_REQUIRED_RESULT static bool transformKeyRaw(const QByteArray& key, const QByteArray& seed, quint32 version, + Type type, quint32 rounds, quint64 memory, quint32 parallelism, diff --git a/src/format/KeePass2.cpp b/src/format/KeePass2.cpp index dc50ca0016..bf5bb1cae3 100644 --- a/src/format/KeePass2.cpp +++ b/src/format/KeePass2.cpp @@ -30,7 +30,8 @@ const QUuid KeePass2::CIPHER_CHACHA20 = QUuid("d6038a2b-8b6f-4cb5-a524-339a31dbb const QUuid KeePass2::KDF_AES_KDBX3 = QUuid("c9d9f39a-628a-4460-bf74-0d08c18a4fea"); const QUuid KeePass2::KDF_AES_KDBX4 = QUuid("7c02bb82-79a7-4ac0-927d-114a00648238"); -const QUuid KeePass2::KDF_ARGON2 = QUuid("ef636ddf-8c29-444b-91f7-a9a403e30a0c"); +const QUuid KeePass2::KDF_ARGON2D = QUuid("ef636ddf-8c29-444b-91f7-a9a403e30a0c"); +const QUuid KeePass2::KDF_ARGON2ID = QUuid("9e298b19-56db-4773-b23d-fc3ec6f0a1e6"); const QByteArray KeePass2::INNER_STREAM_SALSA20_IV("\xe8\x30\x09\x4b\x97\x20\x5d\x2a"); @@ -53,7 +54,8 @@ const QList> KeePass2::CIPHERS{ qMakePair(KeePass2::CIPHER_CHACHA20, QObject::tr("ChaCha20 256-bit"))}; const QList> KeePass2::KDFS{ - qMakePair(KeePass2::KDF_ARGON2, QObject::tr("Argon2 (KDBX 4 – recommended)")), + qMakePair(KeePass2::KDF_ARGON2D, QObject::tr("Argon2d (KDBX 4 – recommended)")), + qMakePair(KeePass2::KDF_ARGON2ID, QObject::tr("Argon2id (KDBX 4)")), qMakePair(KeePass2::KDF_AES_KDBX4, QObject::tr("AES-KDF (KDBX 4)")), qMakePair(KeePass2::KDF_AES_KDBX3, QObject::tr("AES-KDF (KDBX 3.1)"))}; @@ -109,8 +111,11 @@ QSharedPointer KeePass2::uuidToKdf(const QUuid& uuid) if (uuid == KDF_AES_KDBX4) { return QSharedPointer::create(); } - if (uuid == KDF_ARGON2) { - return QSharedPointer::create(); + if (uuid == KDF_ARGON2D) { + return QSharedPointer::create(Argon2Kdf::Type::Argon2d); + } + if (uuid == KDF_ARGON2ID) { + return QSharedPointer::create(Argon2Kdf::Type::Argon2id); } return {}; diff --git a/src/format/KeePass2.h b/src/format/KeePass2.h index d18db3578e..abb24a8000 100644 --- a/src/format/KeePass2.h +++ b/src/format/KeePass2.h @@ -53,7 +53,8 @@ namespace KeePass2 extern const QUuid KDF_AES_KDBX3; extern const QUuid KDF_AES_KDBX4; - extern const QUuid KDF_ARGON2; + extern const QUuid KDF_ARGON2D; + extern const QUuid KDF_ARGON2ID; extern const QByteArray INNER_STREAM_SALSA20_IV; diff --git a/src/format/OpVaultReader.cpp b/src/format/OpVaultReader.cpp index a64b009ded..dab08bd822 100644 --- a/src/format/OpVaultReader.cpp +++ b/src/format/OpVaultReader.cpp @@ -72,7 +72,7 @@ Database* OpVaultReader::readDatabase(QDir& opdataDir, const QString& password) key->addKey(QSharedPointer::create(password)); QScopedPointer db(new Database()); - db->setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2)); + db->setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D)); db->setCipher(KeePass2::CIPHER_AES256); db->setKey(key, true, false); db->metadata()->setName(vaultName); diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetEncryption.cpp b/src/gui/dbsettings/DatabaseSettingsWidgetEncryption.cpp index cc57e453af..2df1f28f01 100644 --- a/src/gui/dbsettings/DatabaseSettingsWidgetEncryption.cpp +++ b/src/gui/dbsettings/DatabaseSettingsWidgetEncryption.cpp @@ -43,7 +43,7 @@ DatabaseSettingsWidgetEncryption::DatabaseSettingsWidgetEncryption(QWidget* pare connect(m_ui->memorySpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryChanged(int))); connect(m_ui->parallelismSpinBox, SIGNAL(valueChanged(int)), this, SLOT(parallelismChanged(int))); - m_ui->compatibilitySelection->addItem(tr("KDBX 4.0 (recommended)"), KeePass2::KDF_ARGON2.toByteArray()); + m_ui->compatibilitySelection->addItem(tr("KDBX 4.0 (recommended)"), KeePass2::KDF_ARGON2D.toByteArray()); m_ui->compatibilitySelection->addItem(tr("KDBX 3.1"), KeePass2::KDF_AES_KDBX3.toByteArray()); m_ui->decryptionTimeSlider->setMinimum(Kdf::MIN_ENCRYPTION_TIME / 100); m_ui->decryptionTimeSlider->setMaximum(Kdf::MAX_ENCRYPTION_TIME / 100); @@ -75,6 +75,9 @@ DatabaseSettingsWidgetEncryption::~DatabaseSettingsWidgetEncryption() { } +#define IS_ARGON2(uuid) (uuid == KeePass2::KDF_ARGON2D || uuid == KeePass2::KDF_ARGON2ID) +#define IS_AES_KDF(uuid) (uuid == KeePass2::KDF_AES_KDBX3 || uuid == KeePass2::KDF_AES_KDBX4) + void DatabaseSettingsWidgetEncryption::initialize() { Q_ASSERT(m_db); @@ -85,7 +88,7 @@ void DatabaseSettingsWidgetEncryption::initialize() bool isDirty = false; if (!m_db->kdf()) { - m_db->setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2)); + m_db->setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D)); isDirty = true; } if (!m_db->key()) { @@ -175,7 +178,7 @@ void DatabaseSettingsWidgetEncryption::loadKdfParameters() } m_ui->transformRoundsSpinBox->setValue(kdf->rounds()); - if (m_db->kdf()->uuid() == KeePass2::KDF_ARGON2) { + if (IS_ARGON2(m_db->kdf()->uuid())) { auto argon2Kdf = kdf.staticCast(); m_ui->memorySpinBox->setValue(static_cast(argon2Kdf->memory()) / (1 << 10)); m_ui->parallelismSpinBox->setValue(argon2Kdf->parallelism()); @@ -188,13 +191,10 @@ void DatabaseSettingsWidgetEncryption::updateKdfFields() { QUuid id = m_db->kdf()->uuid(); - bool memoryVisible = (id == KeePass2::KDF_ARGON2); - m_ui->memoryUsageLabel->setVisible(memoryVisible); - m_ui->memorySpinBox->setVisible(memoryVisible); - - bool parallelismVisible = (id == KeePass2::KDF_ARGON2); - m_ui->parallelismLabel->setVisible(parallelismVisible); - m_ui->parallelismSpinBox->setVisible(parallelismVisible); + m_ui->memoryUsageLabel->setVisible(IS_ARGON2(id)); + m_ui->memorySpinBox->setVisible(IS_ARGON2(id)); + m_ui->parallelismLabel->setVisible(IS_ARGON2(id)); + m_ui->parallelismSpinBox->setVisible(IS_ARGON2(id)); } void DatabaseSettingsWidgetEncryption::activateChangeDecryptionTime() @@ -253,7 +253,7 @@ bool DatabaseSettingsWidgetEncryption::save() m_db->metadata()->customData()->remove(CD_DECRYPTION_TIME_PREFERENCE_KEY); // first perform safety check for KDF rounds - if (kdf->uuid() == KeePass2::KDF_ARGON2 && m_ui->transformRoundsSpinBox->value() > 10000) { + if (IS_ARGON2(kdf->uuid()) && m_ui->transformRoundsSpinBox->value() > 10000) { QMessageBox warning; warning.setIcon(QMessageBox::Warning); warning.setWindowTitle(tr("Number of rounds too high", "Key transformation rounds")); @@ -266,8 +266,7 @@ bool DatabaseSettingsWidgetEncryption::save() if (warning.clickedButton() != ok) { return false; } - } else if ((kdf->uuid() == KeePass2::KDF_AES_KDBX3 || kdf->uuid() == KeePass2::KDF_AES_KDBX4) - && m_ui->transformRoundsSpinBox->value() < 100000) { + } else if (IS_AES_KDF(kdf->uuid()) && m_ui->transformRoundsSpinBox->value() < 100000) { QMessageBox warning; warning.setIcon(QMessageBox::Warning); warning.setWindowTitle(tr("Number of rounds too low", "Key transformation rounds")); @@ -286,7 +285,7 @@ bool DatabaseSettingsWidgetEncryption::save() // Save kdf parameters kdf->setRounds(m_ui->transformRoundsSpinBox->value()); - if (kdf->uuid() == KeePass2::KDF_ARGON2) { + if (IS_ARGON2(kdf->uuid())) { auto argon2Kdf = kdf.staticCast(); argon2Kdf->setMemory(static_cast(m_ui->memorySpinBox->value()) * (1 << 10)); argon2Kdf->setParallelism(static_cast(m_ui->parallelismSpinBox->value())); @@ -317,7 +316,7 @@ void DatabaseSettingsWidgetEncryption::benchmarkTransformRounds(int millisecs) // Create a new kdf with the current parameters auto kdf = KeePass2::uuidToKdf(QUuid(m_ui->kdfComboBox->currentData().toByteArray())); kdf->setRounds(m_ui->transformRoundsSpinBox->value()); - if (kdf->uuid() == KeePass2::KDF_ARGON2) { + if (IS_ARGON2(kdf->uuid())) { auto argon2Kdf = kdf.staticCast(); if (!argon2Kdf->setMemory(static_cast(m_ui->memorySpinBox->value()) * (1 << 10))) { m_ui->memorySpinBox->setValue(static_cast(argon2Kdf->memory() / (1 << 10))); @@ -402,7 +401,7 @@ void DatabaseSettingsWidgetEncryption::updateFormatCompatibility(int index, bool auto kdf = KeePass2::uuidToKdf(kdfUuid); m_db->setKdf(kdf); - if (kdf->uuid() == KeePass2::KDF_ARGON2) { + if (IS_ARGON2(kdf->uuid())) { auto argon2Kdf = kdf.staticCast(); // Default to 64 MiB of memory and 2 threads // these settings are safe for desktop and mobile devices diff --git a/tests/TestKdbx4.cpp b/tests/TestKdbx4.cpp index 51784f062e..46eaacc847 100644 --- a/tests/TestKdbx4.cpp +++ b/tests/TestKdbx4.cpp @@ -42,8 +42,8 @@ int main(int argc, char* argv[]) void TestKdbx4Argon2::initTestCaseImpl() { - m_xmlDb->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2))); - m_kdbxSourceDb->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2))); + m_xmlDb->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D))); + m_kdbxSourceDb->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D))); } QSharedPointer @@ -108,7 +108,7 @@ void TestKdbx4Argon2::readKdbx(const QString& path, void TestKdbx4Argon2::writeKdbx(QIODevice* device, Database* db, bool& hasError, QString& errorString) { if (db->kdf()->uuid() == KeePass2::KDF_AES_KDBX3) { - db->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2))); + db->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D))); } KeePass2Writer writer; hasError = writer.writeDatabase(device, db); @@ -213,26 +213,32 @@ void TestKdbx4Argon2::testFormat400Upgrade_data() auto constexpr kdbx3 = KeePass2::FILE_VERSION_3_1 & KeePass2::FILE_VERSION_CRITICAL_MASK; auto constexpr kdbx4 = KeePass2::FILE_VERSION_4 & KeePass2::FILE_VERSION_CRITICAL_MASK; - QTest::newRow("Argon2 + AES") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_AES256 << false << kdbx4; - QTest::newRow("AES-KDF + AES") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_AES256 << false << kdbx4; - QTest::newRow("AES-KDF (legacy) + AES") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_AES256 << false << kdbx3; - QTest::newRow("Argon2 + AES + CustomData") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_AES256 << true << kdbx4; - QTest::newRow("AES-KDF + AES + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_AES256 << true << kdbx4; - QTest::newRow("AES-KDF (legacy) + AES + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_AES256 << true << kdbx4; - - QTest::newRow("Argon2 + ChaCha20") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_CHACHA20 << false << kdbx4; - QTest::newRow("AES-KDF + ChaCha20") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_CHACHA20 << false << kdbx4; - QTest::newRow("AES-KDF (legacy) + ChaCha20") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_CHACHA20 << false << kdbx3; - QTest::newRow("Argon2 + ChaCha20 + CustomData") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_CHACHA20 << true << kdbx4; - QTest::newRow("AES-KDF + ChaCha20 + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_CHACHA20 << true << kdbx4; - QTest::newRow("AES-KDF (legacy) + ChaCha20 + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_CHACHA20 << true << kdbx4; - - QTest::newRow("Argon2 + Twofish") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_TWOFISH << false << kdbx4; - QTest::newRow("AES-KDF + Twofish") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_TWOFISH << false << kdbx4; - QTest::newRow("AES-KDF (legacy) + Twofish") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_TWOFISH << false << kdbx3; - QTest::newRow("Argon2 + Twofish + CustomData") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_TWOFISH << true << kdbx4; - QTest::newRow("AES-KDF + Twofish + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_TWOFISH << true << kdbx4; - QTest::newRow("AES-KDF (legacy) + Twofish + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_TWOFISH << true << kdbx4; + QTest::newRow("Argon2d + AES") << KeePass2::KDF_ARGON2D << KeePass2::CIPHER_AES256 << false << kdbx4; + QTest::newRow("Argon2id + AES") << KeePass2::KDF_ARGON2ID << KeePass2::CIPHER_AES256 << false << kdbx4; + QTest::newRow("AES-KDF + AES") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_AES256 << false << kdbx4; + QTest::newRow("AES-KDF (legacy) + AES") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_AES256 << false << kdbx3; + QTest::newRow("Argon2d + AES + CustomData") << KeePass2::KDF_ARGON2D << KeePass2::CIPHER_AES256 << true << kdbx4; + QTest::newRow("Argon2id + AES + CustomData") << KeePass2::KDF_ARGON2ID << KeePass2::CIPHER_AES256 << true << kdbx4; + QTest::newRow("AES-KDF + AES + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_AES256 << true << kdbx4; + QTest::newRow("AES-KDF (legacy) + AES + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_AES256 << true << kdbx4; + + QTest::newRow("Argon2d + ChaCha20") << KeePass2::KDF_ARGON2D << KeePass2::CIPHER_CHACHA20 << false << kdbx4; + QTest::newRow("Argon2id + ChaCha20") << KeePass2::KDF_ARGON2ID << KeePass2::CIPHER_CHACHA20 << false << kdbx4; + QTest::newRow("AES-KDF + ChaCha20") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_CHACHA20 << false << kdbx4; + QTest::newRow("AES-KDF (legacy) + ChaCha20") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_CHACHA20 << false << kdbx3; + QTest::newRow("Argon2d + ChaCha20 + CustomData") << KeePass2::KDF_ARGON2D << KeePass2::CIPHER_CHACHA20 << true << kdbx4; + QTest::newRow("Argon2id + ChaCha20 + CustomData") << KeePass2::KDF_ARGON2ID << KeePass2::CIPHER_CHACHA20 << true << kdbx4; + QTest::newRow("AES-KDF + ChaCha20 + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_CHACHA20 << true << kdbx4; + QTest::newRow("AES-KDF (legacy) + ChaCha20 + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_CHACHA20 << true << kdbx4; + + QTest::newRow("Argon2d + Twofish") << KeePass2::KDF_ARGON2D << KeePass2::CIPHER_TWOFISH << false << kdbx4; + QTest::newRow("Argon2id + Twofish") << KeePass2::KDF_ARGON2ID << KeePass2::CIPHER_TWOFISH << false << kdbx4; + QTest::newRow("AES-KDF + Twofish") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_TWOFISH << false << kdbx4; + QTest::newRow("AES-KDF (legacy) + Twofish") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_TWOFISH << false << kdbx3; + QTest::newRow("Argon2d + Twofish + CustomData") << KeePass2::KDF_ARGON2D << KeePass2::CIPHER_TWOFISH << true << kdbx4; + QTest::newRow("Argon2id + Twofish + CustomData") << KeePass2::KDF_ARGON2ID << KeePass2::CIPHER_TWOFISH << true << kdbx4; + QTest::newRow("AES-KDF + Twofish + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_TWOFISH << true << kdbx4; + QTest::newRow("AES-KDF (legacy) + Twofish + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_TWOFISH << true << kdbx4; } // clang-format on @@ -270,7 +276,7 @@ void TestKdbx4Argon2::testUpgradeMasterKeyIntegrity() } else if (upgradeAction == "kdf-aes-kdbx3") { db->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_AES_KDBX3))); } else if (upgradeAction == "kdf-argon2") { - db->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2))); + db->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D))); } else if (upgradeAction == "kdf-aes-kdbx4") { db->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_AES_KDBX4))); } else if (upgradeAction == "public-customdata") { diff --git a/tests/TestKeePass2Format.cpp b/tests/TestKeePass2Format.cpp index b0217c9429..2aa3948aec 100644 --- a/tests/TestKeePass2Format.cpp +++ b/tests/TestKeePass2Format.cpp @@ -809,7 +809,7 @@ QSharedPointer TestKeePass2Format::fastKdf(QSharedPointer kdf) const { kdf->setRounds(1); - if (kdf->uuid() == KeePass2::KDF_ARGON2) { + if (kdf->uuid() == KeePass2::KDF_ARGON2D) { kdf->processParameters({{KeePass2::KDFPARAM_ARGON2_MEMORY, 1024}, {KeePass2::KDFPARAM_ARGON2_PARALLELISM, 1}}); } diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index c79de84bba..4ab29ce370 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -302,7 +302,7 @@ void TestGui::testCreateDatabase() // check key and encryption QCOMPARE(m_db->key()->keys().size(), 2); QCOMPARE(m_db->kdf()->rounds(), 2); - QCOMPARE(m_db->kdf()->uuid(), KeePass2::KDF_ARGON2); + QCOMPARE(m_db->kdf()->uuid(), KeePass2::KDF_ARGON2D); QCOMPARE(m_db->cipher(), KeePass2::CIPHER_AES256); auto compositeKey = QSharedPointer::create(); compositeKey->addKey(QSharedPointer::create("test"));