From 92ca09147fc239762927595165f71a0d1ecff98f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 13 Sep 2017 19:20:46 -0700 Subject: Restore compatibility with pre-5.9 Keccak calculation Commit 12c5264d9add1826d543c36d893db77262195fc6 fixed the calculation of SHA-3 in QCryptographicHash: we were previously calculating Keccak. Unfortunately, turns out that replacing the algorithm wasn't the best idea: there are people who need to compare with the result obtained from a previous version of Qt and stored somewhere. This commit restores the enum values 7 through 10 to mean Keccak and moves SHA-3 to 12 through 15. The "Sha3_nnn" enums will switch between the two according to the QT_SHA3_KECCAK_COMPAT macro. [ChangeLog][Important Behavior Changes] This version of Qt restores compatibility with pre-5.9.0 calculation of QCryptographicHash algorithms that were labelled "Sha3_nnn": that is, applications compiled with old versions of Qt will continue using the Keccak algorithm. Applications recompiled with this version will use SHA-3, unless QT_SHA3_KECCAK_COMPAT is #define'd prior to #include . [ChangeLog][Binary Compatibility Note] This version of Qt changes the values assigned to enumerations QCryptographicHash::Sha3_nnn. Applications compiled with this version and using those enumerations will not work with Qt 5.9.0 and 5.9.1, unless QT_SHA3_KECCAK_COMPAT is defined. Task-number: QTBUG-62025 Discussed-at: http://lists.qt-project.org/pipermail/development/2017-September/030818.html Change-Id: I6e1fe42ae4b742a7b811fffd14e418fc04f096c3 Reviewed-by: Lars Knoll --- src/corelib/tools/qcryptographichash.cpp | 89 +++++++++++++++++----- src/corelib/tools/qcryptographichash.h | 24 +++++- src/corelib/tools/qmessageauthenticationcode.cpp | 12 ++- .../corelib/tools/qcryptographichash/main.cpp | 8 ++ 4 files changed, 106 insertions(+), 27 deletions(-) diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index 5410adc737..a1b121f1ee 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -181,13 +181,18 @@ public: #endif }; #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 - void sha3Finish(int bitCount); + enum class Sha3Variant + { + Sha3, + Keccak + }; + void sha3Finish(int bitCount, Sha3Variant sha3Variant); #endif QByteArray result; }; #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 -void QCryptographicHashPrivate::sha3Finish(int bitCount) +void QCryptographicHashPrivate::sha3Finish(int bitCount, Sha3Variant sha3Variant) { /* FIPS 202 ยง6.1 defines SHA-3 in terms of calculating the Keccak function @@ -214,7 +219,15 @@ void QCryptographicHashPrivate::sha3Finish(int bitCount) result.resize(bitCount / 8); SHA3Context copy = sha3Context; - sha3Update(©, reinterpret_cast(&sha3FinalSuffix), 2); + + switch (sha3Variant) { + case Sha3Variant::Sha3: + sha3Update(©, reinterpret_cast(&sha3FinalSuffix), 2); + break; + case Sha3Variant::Keccak: + break; + } + sha3Final(©, reinterpret_cast(result.data())); } #endif @@ -239,6 +252,12 @@ void QCryptographicHashPrivate::sha3Finish(int bitCount) /*! \enum QCryptographicHash::Algorithm + \note In Qt versions before 5.9, when asked to generate a SHA3 hash sum, + QCryptographicHash actually calculated Keccak. If you need compatibility with + SHA-3 hashes produced by those versions of Qt, use the \c{Keccak_} + enumerators. Alternatively, if source compatibility is required, define the + macro \c QT_SHA3_KECCAK_COMPAT. + \value Md4 Generate an MD4 hash sum \value Md5 Generate an MD5 hash sum \value Sha1 Generate an SHA-1 hash sum @@ -250,6 +269,14 @@ void QCryptographicHashPrivate::sha3Finish(int bitCount) \value Sha3_256 Generate an SHA3-256 hash sum. Introduced in Qt 5.1 \value Sha3_384 Generate an SHA3-384 hash sum. Introduced in Qt 5.1 \value Sha3_512 Generate an SHA3-512 hash sum. Introduced in Qt 5.1 + \value Keccak_224 Generate a Keccak-224 hash sum. Introduced in Qt 5.9.2 + \value Keccak_256 Generate a Keccak-256 hash sum. Introduced in Qt 5.9.2 + \value Keccak_384 Generate a Keccak-384 hash sum. Introduced in Qt 5.9.2 + \value Keccak_512 Generate a Keccak-512 hash sum. Introduced in Qt 5.9.2 + \omitvalue RealSha3_224 + \omitvalue RealSha3_256 + \omitvalue RealSha3_384 + \omitvalue RealSha3_512 */ /*! @@ -303,16 +330,20 @@ void QCryptographicHash::reset() case Sha512: SHA512Reset(&d->sha512Context); break; - case Sha3_224: + case RealSha3_224: + case Keccak_224: sha3Init(&d->sha3Context, 224); break; - case Sha3_256: + case RealSha3_256: + case Keccak_256: sha3Init(&d->sha3Context, 256); break; - case Sha3_384: + case RealSha3_384: + case Keccak_384: sha3Init(&d->sha3Context, 384); break; - case Sha3_512: + case RealSha3_512: + case Keccak_512: sha3Init(&d->sha3Context, 512); break; #endif @@ -354,16 +385,20 @@ void QCryptographicHash::addData(const char *data, int length) case Sha512: SHA512Input(&d->sha512Context, reinterpret_cast(data), length); break; - case Sha3_224: + case RealSha3_224: + case Keccak_224: sha3Update(&d->sha3Context, reinterpret_cast(data), length*8); break; - case Sha3_256: + case RealSha3_256: + case Keccak_256: sha3Update(&d->sha3Context, reinterpret_cast(data), length*8); break; - case Sha3_384: + case RealSha3_384: + case Keccak_384: sha3Update(&d->sha3Context, reinterpret_cast(data), length*8); break; - case Sha3_512: + case RealSha3_512: + case Keccak_512: sha3Update(&d->sha3Context, reinterpret_cast(data), length*8); break; #endif @@ -462,20 +497,36 @@ QByteArray QCryptographicHash::result() const SHA512Result(©, reinterpret_cast(d->result.data())); break; } - case Sha3_224: { - d->sha3Finish(224); + case RealSha3_224: { + d->sha3Finish(224, QCryptographicHashPrivate::Sha3Variant::Sha3); + break; + } + case RealSha3_256: { + d->sha3Finish(256, QCryptographicHashPrivate::Sha3Variant::Sha3); + break; + } + case RealSha3_384: { + d->sha3Finish(384, QCryptographicHashPrivate::Sha3Variant::Sha3); + break; + } + case RealSha3_512: { + d->sha3Finish(512, QCryptographicHashPrivate::Sha3Variant::Sha3); + break; + } + case Keccak_224: { + d->sha3Finish(224, QCryptographicHashPrivate::Sha3Variant::Keccak); break; } - case Sha3_256: { - d->sha3Finish(256); + case Keccak_256: { + d->sha3Finish(256, QCryptographicHashPrivate::Sha3Variant::Keccak); break; } - case Sha3_384: { - d->sha3Finish(384); + case Keccak_384: { + d->sha3Finish(384, QCryptographicHashPrivate::Sha3Variant::Keccak); break; } - case Sha3_512: { - d->sha3Finish(512); + case Keccak_512: { + d->sha3Finish(512, QCryptographicHashPrivate::Sha3Variant::Keccak); break; } #endif diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h index 0f17baa036..2f74d42405 100644 --- a/src/corelib/tools/qcryptographichash.h +++ b/src/corelib/tools/qcryptographichash.h @@ -65,10 +65,26 @@ public: Sha256, Sha384, Sha512, - Sha3_224, - Sha3_256, - Sha3_384, - Sha3_512 + + Keccak_224 = 7, + Keccak_256, + Keccak_384, + Keccak_512, + RealSha3_224 = 11, + RealSha3_256, + RealSha3_384, + RealSha3_512, +# ifndef QT_SHA3_KECCAK_COMPAT + Sha3_224 = RealSha3_224, + Sha3_256 = RealSha3_256, + Sha3_384 = RealSha3_384, + Sha3_512 = RealSha3_512 +# else + Sha3_224 = Keccak_224, + Sha3_256 = Keccak_256, + Sha3_384 = Keccak_384, + Sha3_512 = Keccak_512 +# endif #endif }; Q_ENUM(Algorithm) diff --git a/src/corelib/tools/qmessageauthenticationcode.cpp b/src/corelib/tools/qmessageauthenticationcode.cpp index 9a84191452..40a1193622 100644 --- a/src/corelib/tools/qmessageauthenticationcode.cpp +++ b/src/corelib/tools/qmessageauthenticationcode.cpp @@ -99,13 +99,17 @@ static int qt_hash_block_size(QCryptographicHash::Algorithm method) return SHA384_Message_Block_Size; case QCryptographicHash::Sha512: return SHA512_Message_Block_Size; - case QCryptographicHash::Sha3_224: + case QCryptographicHash::RealSha3_224: + case QCryptographicHash::Keccak_224: return 144; - case QCryptographicHash::Sha3_256: + case QCryptographicHash::RealSha3_256: + case QCryptographicHash::Keccak_256: return 136; - case QCryptographicHash::Sha3_384: + case QCryptographicHash::RealSha3_384: + case QCryptographicHash::Keccak_384: return 104; - case QCryptographicHash::Sha3_512: + case QCryptographicHash::RealSha3_512: + case QCryptographicHash::Keccak_512: return 72; } return 0; diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp b/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp index 5799b32b1c..507e2af708 100644 --- a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp +++ b/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp @@ -79,6 +79,14 @@ const char *algoname(int i) return "sha3_384-"; case QCryptographicHash::Sha3_512: return "sha3_512-"; + case QCryptographicHash::Keccak_224: + return "keccak_224-"; + case QCryptographicHash::Keccak_256: + return "keccak_256-"; + case QCryptographicHash::Keccak_384: + return "keccak_384-"; + case QCryptographicHash::Keccak_512: + return "keccak_512-"; } Q_UNREACHABLE(); return 0; -- cgit v1.2.3