Add Argon2id KDF

This commit is contained in:
Janek Bevendorff 2020-11-20 21:49:56 +01:00
parent c6bd22aa12
commit 9a96124040
9 changed files with 93 additions and 54 deletions

View file

@ -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<Argon2Kdf>();
m_ui->memorySpinBox->setValue(static_cast<int>(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>();
argon2Kdf->setMemory(static_cast<quint64>(m_ui->memorySpinBox->value()) * (1 << 10));
argon2Kdf->setParallelism(static_cast<quint32>(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<Argon2Kdf>();
if (!argon2Kdf->setMemory(static_cast<quint64>(m_ui->memorySpinBox->value()) * (1 << 10))) {
m_ui->memorySpinBox->setValue(static_cast<int>(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<Argon2Kdf>();
// Default to 64 MiB of memory and 2 threads
// these settings are safe for desktop and mobile devices