diff options
author | Jonathan White <support@dmapps.us> | 2018-01-05 18:41:29 +0300 |
---|---|---|
committer | Jonathan White <support@dmapps.us> | 2018-01-13 22:24:55 +0300 |
commit | bef7ba2cfed00b88175473ae68481cebb7746098 (patch) | |
tree | 08f185e94f6ef7705174a70ea979576c81478e15 /src/format/KeePass2.cpp | |
parent | 7dba788d09b3333087961e6fa2af4b02579999b4 (diff) |
Implements KDBX4 format with Argon2 KDF
* Adds KDBX4 reader/writer interfaces
* Adds KDBX4 XML reader/write interfaces
* Implements test cases for KDBX4
* Fully compatible with KeePass2
* Corrects minor issues with Argon2 KDF
Diffstat (limited to 'src/format/KeePass2.cpp')
-rw-r--r-- | src/format/KeePass2.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/format/KeePass2.cpp b/src/format/KeePass2.cpp index fd57148d0..f89e828a1 100644 --- a/src/format/KeePass2.cpp +++ b/src/format/KeePass2.cpp @@ -19,6 +19,7 @@ #include <QSharedPointer> #include "crypto/kdf/AesKdf.h" #include "crypto/kdf/Argon2Kdf.h" +#include "crypto/CryptoHash.h" const Uuid KeePass2::CIPHER_AES = Uuid(QByteArray::fromHex("31c1f2e6bf714350be5805216afc5aff")); const Uuid KeePass2::CIPHER_TWOFISH = Uuid(QByteArray::fromHex("ad68f29f576f4bb9a36ad47af965346c")); @@ -29,6 +30,19 @@ const Uuid KeePass2::KDF_ARGON2 = Uuid(QByteArray::fromHex("EF636DDF8C29444B91F7 const QByteArray KeePass2::INNER_STREAM_SALSA20_IV("\xE8\x30\x09\x4B\x97\x20\x5D\x2A"); +const QString KeePass2::KDFPARAM_UUID("$UUID"); +// AES parameters +const QString KeePass2::KDFPARAM_AES_ROUNDS("R"); +const QString KeePass2::KDFPARAM_AES_SEED("S"); +// Argon2 parameters +const QString KeePass2::KDFPARAM_ARGON2_SALT("S"); +const QString KeePass2::KDFPARAM_ARGON2_PARALLELISM("P"); +const QString KeePass2::KDFPARAM_ARGON2_MEMORY("M"); +const QString KeePass2::KDFPARAM_ARGON2_ITERATIONS("I"); +const QString KeePass2::KDFPARAM_ARGON2_VERSION("V"); +const QString KeePass2::KDFPARAM_ARGON2_SECRET("K"); +const QString KeePass2::KDFPARAM_ARGON2_ASSOCDATA("A"); + const QList<QPair<Uuid, QString>> KeePass2::CIPHERS { qMakePair(KeePass2::CIPHER_AES, QObject::tr("AES: 256-bit")), qMakePair(KeePass2::CIPHER_TWOFISH, QObject::tr("Twofish: 256-bit")), @@ -39,6 +53,38 @@ const QList<QPair<Uuid, QString>> KeePass2::KDFS { qMakePair(KeePass2::KDF_ARGON2, QObject::tr("Argon2")), }; +QByteArray KeePass2::hmacKey(QByteArray masterSeed, QByteArray transformedMasterKey) { + CryptoHash hmacKeyHash(CryptoHash::Sha512); + hmacKeyHash.addData(masterSeed); + hmacKeyHash.addData(transformedMasterKey); + hmacKeyHash.addData(QByteArray(1, '\x01')); + return hmacKeyHash.result(); +} + +QSharedPointer<Kdf> KeePass2::kdfFromParameters(const QVariantMap &p) +{ + QByteArray uuidBytes = p.value(KDFPARAM_UUID).toByteArray(); + if (uuidBytes.size() != Uuid::Length) { + return nullptr; + } + + QSharedPointer<Kdf> kdf(uuidToKdf(Uuid(uuidBytes))); + if (kdf.isNull()) { + return nullptr; + } + + if (!kdf->processParameters(p)) { + return nullptr; + } + + return kdf; +} + +QVariantMap KeePass2::kdfToParameters(QSharedPointer<Kdf> kdf) +{ + return kdf->writeParameters(); +} + QSharedPointer<Kdf> KeePass2::uuidToKdf(const Uuid& uuid) { if (uuid == KDF_AES) { |