Revert back to Argon2 reference library

* Fix #7487 - Botan does not use threads when calculating Argon2 KDF leading to very poor performance for a parallelism value > 1.
* Include port file for vcpkg backed builds
This commit is contained in:
Jonathan White 2022-03-05 10:45:57 -05:00
parent 93624c3700
commit e5a2958458
7 changed files with 107 additions and 20 deletions

View File

@ -494,6 +494,10 @@ if(BOTAN2_VERSION VERSION_LESS "2.11.0")
message(FATAL_ERROR "Botan2 2.11.0 or higher is required")
endif()
include_directories(SYSTEM ${BOTAN2_INCLUDE_DIR})
# Find Argon2 -- Botan 2.18 and below does not support threaded Argon2
find_library(ARGON2_LIBRARIES NAMES argon2)
find_path(ARGON2_INCLUDE_DIR NAMES argon2.h PATH_SUFFIXES local/include)
include_directories(SYSTEM ${ARGON2_INCLUDE_DIR})
# Find zlib
find_package(ZLIB REQUIRED)

View File

@ -336,6 +336,7 @@ target_link_libraries(keepassx_core
${PCSC_LIBRARIES}
${ZXCVBN_LIBRARIES}
${ZLIB_LIBRARIES}
${ARGON2_LIBRARIES}
${thirdparty_LIBRARIES}
)

View File

@ -17,8 +17,10 @@
#include "Argon2Kdf.h"
#include <QElapsedTimer>
#include <QThread>
#include <botan/pwdhash.h>
#include <argon2.h>
#include "format/KeePass2.h"
@ -163,20 +165,27 @@ bool Argon2Kdf::transform(const QByteArray& raw, QByteArray& result) const
{
result.clear();
result.resize(32);
try {
auto algo = type() == Type::Argon2d ? "Argon2d" : "Argon2id";
auto pwhash = Botan::PasswordHashFamily::create_or_throw(algo)->from_params(memory(), rounds(), parallelism());
pwhash->derive_key(reinterpret_cast<uint8_t*>(result.data()),
result.size(),
raw.constData(),
raw.size(),
reinterpret_cast<const uint8_t*>(seed().constData()),
seed().size());
return true;
} catch (std::exception& e) {
qWarning("Argon2 error: %s", e.what());
// Time Cost, Mem Cost, Threads/Lanes, Password, length, Salt, length, out, length
int rc = argon2_hash(rounds(),
memory(),
parallelism(),
raw.data(),
raw.size(),
seed().data(),
seed().size(),
result.data(),
result.size(),
nullptr,
0,
type() == Type::Argon2d ? Argon2_d : Argon2_id,
version());
if (rc != ARGON2_OK) {
qWarning("Argon2 error: %s", argon2_error_message(rc));
return false;
}
return true;
}
QSharedPointer<Kdf> Argon2Kdf::clone() const
@ -186,14 +195,16 @@ QSharedPointer<Kdf> Argon2Kdf::clone() const
int Argon2Kdf::benchmark(int msec) const
{
try {
auto algo = type() == Type::Argon2d ? "Argon2d" : "Argon2id";
auto pwhash = Botan::PasswordHashFamily::create_or_throw(algo)->tune(
32, std::chrono::milliseconds(msec), memory() / 1024);
return qMax(static_cast<size_t>(1), pwhash->iterations());
} catch (std::exception& e) {
return 1;
QByteArray key = QByteArray(16, '\x7E');
QElapsedTimer timer;
timer.start();
if (transform(key, key)) {
return static_cast<int>(rounds() * (static_cast<float>(msec) / timer.elapsed()));
}
return 1;
}
QString Argon2Kdf::toString() const

View File

@ -325,6 +325,8 @@ void DatabaseSettingsWidgetEncryption::benchmarkTransformRounds(int millisecs)
kdf->setRounds(m_ui->transformRoundsSpinBox->value());
if (IS_ARGON2(kdf->uuid())) {
auto argon2Kdf = kdf.staticCast<Argon2Kdf>();
// Set a small static number of rounds for the benchmark
argon2Kdf->setRounds(4);
if (!argon2Kdf->setMemory(static_cast<quint64>(m_ui->memorySpinBox->value()) * (1 << 10))) {
m_ui->memorySpinBox->setValue(static_cast<int>(argon2Kdf->memory() / (1 << 10)));
}

View File

@ -0,0 +1,37 @@
cmake_minimum_required(VERSION 3.8)
project(argon2 C)
set(PROJECT_VERSION 20190702)
if(MSVC)
add_compile_options(/W3)
endif()
include_directories(include src)
set(SRC
src/argon2.c
src/core.c
src/encoding.c
src/ref.c
src/thread.c
src/opt.c
src/blake2/blake2b.c
)
set(HEADERS
include/argon2.h
)
add_library(argon2 ${SRC})
install(
TARGETS argon2
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
if(NOT DISABLE_INSTALL_HEADERS)
install(FILES ${HEADERS} DESTINATION include)
endif()

View File

@ -0,0 +1,25 @@
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO P-H-C/phc-winner-argon2
REF 20190702
SHA512 0a4cb89e8e63399f7df069e2862ccd05308b7652bf4ab74372842f66bcc60776399e0eaf979a7b7e31436b5e6913fe5b0a6949549d8c82ebd06e0629b106e85f
HEAD_REF master
)
configure_file(${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt ${SOURCE_PATH}/CMakeLists.txt COPYONLY)
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
PREFER_NINJA
OPTIONS
${FEATURE_OPTIONS}
OPTIONS_DEBUG
-DDISABLE_INSTALL_HEADERS=ON
)
vcpkg_install_cmake()
vcpkg_copy_pdbs()
file(INSTALL ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright)

View File

@ -0,0 +1,7 @@
{
"name": "argon2",
"version-string": "20190702",
"port-version": 1,
"description": "Reference C implementation of Argon2, the password-hashing function that won the Password Hashing Competition (PHC).",
"homepage": "https://github.com/P-H-C/phc-winner-argon2"
}