Add support for various algorithms for kdbx4

* Add SHA512 support to CryptoHash
* Add ChaCha20 support
* Add HMAC support
* Add new HmacBlockStream, used in KDBX 4
* Add support for ChaCha20 protected stream
This commit is contained in:
angelsl 2017-11-13 02:23:01 +08:00 committed by Jonathan White
parent 4532108678
commit 6a0d05e1ef
No known key found for this signature in database
GPG key ID: 440FC65F2E0C6E01
23 changed files with 616 additions and 25 deletions

View file

@ -29,27 +29,42 @@ public:
};
CryptoHash::CryptoHash(CryptoHash::Algorithm algo)
: CryptoHash::CryptoHash(algo, false) {}
CryptoHash::CryptoHash(CryptoHash::Algorithm algo, bool hmac)
: d_ptr(new CryptoHashPrivate())
{
Q_D(CryptoHash);
Q_ASSERT(Crypto::initalized());
int algoGcrypt;
int algoGcrypt = -1;
unsigned int flagsGcrypt = 0;
switch (algo) {
case CryptoHash::Sha256:
algoGcrypt = GCRY_MD_SHA256;
break;
case CryptoHash::Sha512:
algoGcrypt = GCRY_MD_SHA512;
break;
default:
Q_ASSERT(false);
break;
}
gcry_error_t error = gcry_md_open(&d->ctx, algoGcrypt, 0);
if (hmac) {
flagsGcrypt |= GCRY_MD_FLAG_HMAC;
}
gcry_error_t error = gcry_md_open(&d->ctx, algoGcrypt, flagsGcrypt);
if (error) {
qWarning("Gcrypt error (ctor): %s", gcry_strerror(error));
qWarning("Gcrypt error (ctor): %s", gcry_strsource(error));
}
Q_ASSERT(error == 0); // TODO: error handling
Q_UNUSED(error);
d->hashLen = gcry_md_get_algo_dlen(algoGcrypt);
}
@ -74,6 +89,18 @@ void CryptoHash::addData(const QByteArray& data)
gcry_md_write(d->ctx, data.constData(), data.size());
}
void CryptoHash::setKey(const QByteArray& data)
{
Q_D(CryptoHash);
gcry_error_t error = gcry_md_setkey(d->ctx, data.constData(), data.size());
if (error) {
qWarning("Gcrypt error (setKey): %s", gcry_strerror(error));
qWarning("Gcrypt error (setKey): %s", gcry_strsource(error));
}
Q_ASSERT(error == 0);
}
void CryptoHash::reset()
{
Q_D(CryptoHash);
@ -96,3 +123,12 @@ QByteArray CryptoHash::hash(const QByteArray& data, CryptoHash::Algorithm algo)
cryptoHash.addData(data);
return cryptoHash.result();
}
QByteArray CryptoHash::hmac(const QByteArray& data, const QByteArray& key, CryptoHash::Algorithm algo)
{
// replace with gcry_md_hash_buffer()?
CryptoHash cryptoHash(algo, true);
cryptoHash.setKey(key);
cryptoHash.addData(data);
return cryptoHash.result();
}