diff options
Diffstat (limited to 'src/corelib/tools/qcryptographichash.cpp')
-rw-r--r-- | src/corelib/tools/qcryptographichash.cpp | 161 |
1 files changed, 138 insertions, 23 deletions
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index 3f17fe15aa..32f5f0b33a 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Richard J. Moore <rich@kde.org>. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -40,12 +41,51 @@ ****************************************************************************/ #include <qcryptographichash.h> +#include <qiodevice.h> + +#include "../../3rdparty/sha1/sha1.cpp" +#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 +// qdoc only needs SHA-1 #include "../../3rdparty/md5/md5.h" #include "../../3rdparty/md5/md5.cpp" #include "../../3rdparty/md4/md4.h" #include "../../3rdparty/md4/md4.cpp" -#include "../../3rdparty/sha1/sha1.cpp" + +typedef unsigned char BitSequence; +typedef unsigned long long DataLength; +typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; + +#include "../../3rdparty/sha3/KeccakSponge.c" +typedef spongeState hashState; + +#include "../../3rdparty/sha3/KeccakNISTInterface.c" + +/* + This lets us choose between SHA3 implementations at build time. + */ +typedef spongeState SHA3Context; +typedef HashReturn (SHA3Init)(hashState *state, int hashbitlen); +typedef HashReturn (SHA3Update)(hashState *state, const BitSequence *data, DataLength databitlen); +typedef HashReturn (SHA3Final)(hashState *state, BitSequence *hashval); + +#if QT_POINTER_SIZE == 8 // 64 bit version + +#include "../../3rdparty/sha3/KeccakF-1600-opt64.c" + +static SHA3Init * const sha3Init = Init; +static SHA3Update * const sha3Update = Update; +static SHA3Final * const sha3Final = Final; + +#else // 32 bit optimised fallback + +#include "../../3rdparty/sha3/KeccakF-1600-opt32.c" + +static SHA3Init * const sha3Init = Init; +static SHA3Update * const sha3Update = Update; +static SHA3Final * const sha3Final = Final; + +#endif /* These #defines replace the typedefs needed by the RFC6234 code. Normally @@ -88,8 +128,6 @@ static int SHA384_512AddLength(SHA512Context *context, unsigned int length); #undef uint68_t #undef int_least16_t -#include <qiodevice.h> - static inline int SHA224_256AddLength(SHA256Context *context, unsigned int length) { QT_PREPEND_NAMESPACE(quint32) addTemp; @@ -100,6 +138,7 @@ static inline int SHA384_512AddLength(SHA512Context *context, unsigned int lengt QT_PREPEND_NAMESPACE(quint64) addTemp; return SHA384_512AddLengthM(context, length); } +#endif // QT_CRYPTOGRAPHICHASH_ONLY_SHA1 QT_BEGIN_NAMESPACE @@ -108,13 +147,16 @@ class QCryptographicHashPrivate public: QCryptographicHash::Algorithm method; union { + Sha1State sha1Context; +#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 MD5Context md5Context; md4_context md4Context; - Sha1State sha1Context; SHA224Context sha224Context; SHA256Context sha256Context; SHA384Context sha384Context; SHA512Context sha512Context; + SHA3Context sha3Context; +#endif }; QByteArray result; }; @@ -141,10 +183,14 @@ public: \value Md4 Generate an MD4 hash sum \value Md5 Generate an MD5 hash sum \value Sha1 Generate an SHA-1 hash sum - \value Sha224 Generate an SHA-224 hash sum. Introduced in Qt 5.0 - \value Sha256 Generate an SHA-256 hash sum. Introduced in Qt 5.0 - \value Sha384 Generate an SHA-384 hash sum. Introduced in Qt 5.0 - \value Sha512 Generate an SHA-512 hash sum. Introduced in Qt 5.0 + \value Sha224 Generate an SHA-224 hash sum (SHA-2). Introduced in Qt 5.0 + \value Sha256 Generate an SHA-256 hash sum (SHA-2). Introduced in Qt 5.0 + \value Sha384 Generate an SHA-384 hash sum (SHA-2). Introduced in Qt 5.0 + \value Sha512 Generate an SHA-512 hash sum (SHA-2). Introduced in Qt 5.0 + \value Sha3_224 Generate an SHA3-224 hash sum. Introduced in Qt 5.1 + \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 */ /*! @@ -171,15 +217,21 @@ QCryptographicHash::~QCryptographicHash() void QCryptographicHash::reset() { switch (d->method) { + case Sha1: + sha1InitState(&d->sha1Context); + break; +#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 + default: + Q_ASSERT_X(false, "QCryptographicHash", "Method not compiled in"); + Q_UNREACHABLE(); + break; +#else case Md4: md4_init(&d->md4Context); break; case Md5: MD5Init(&d->md5Context); break; - case Sha1: - sha1InitState(&d->sha1Context); - break; case Sha224: SHA224Reset(&d->sha224Context); break; @@ -192,6 +244,19 @@ void QCryptographicHash::reset() case Sha512: SHA512Reset(&d->sha512Context); break; + case Sha3_224: + sha3Init(&d->sha3Context, 224); + break; + case Sha3_256: + sha3Init(&d->sha3Context, 256); + break; + case Sha3_384: + sha3Init(&d->sha3Context, 384); + break; + case Sha3_512: + sha3Init(&d->sha3Context, 512); + break; +#endif } d->result.clear(); } @@ -203,15 +268,21 @@ void QCryptographicHash::reset() void QCryptographicHash::addData(const char *data, int length) { switch (d->method) { + case Sha1: + sha1Update(&d->sha1Context, (const unsigned char *)data, length); + break; +#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 + default: + Q_ASSERT_X(false, "QCryptographicHash", "Method not compiled in"); + Q_UNREACHABLE(); + break; +#else case Md4: md4_update(&d->md4Context, (const unsigned char *)data, length); break; case Md5: MD5Update(&d->md5Context, (const unsigned char *)data, length); break; - case Sha1: - sha1Update(&d->sha1Context, (const unsigned char *)data, length); - break; case Sha224: SHA224Input(&d->sha224Context, reinterpret_cast<const unsigned char *>(data), length); break; @@ -224,7 +295,20 @@ void QCryptographicHash::addData(const char *data, int length) case Sha512: SHA512Input(&d->sha512Context, reinterpret_cast<const unsigned char *>(data), length); break; - } + case Sha3_224: + sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); + break; + case Sha3_256: + sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); + break; + case Sha3_384: + sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); + break; + case Sha3_512: + sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); + break; +#endif + } d->result.clear(); } @@ -266,10 +350,23 @@ bool QCryptographicHash::addData(QIODevice* device) */ QByteArray QCryptographicHash::result() const { - if (!d->result.isEmpty()) + if (!d->result.isEmpty()) return d->result; switch (d->method) { + case Sha1: { + Sha1State copy = d->sha1Context; + d->result.resize(20); + sha1FinalizeState(©); + sha1ToHash(©, (unsigned char *)d->result.data()); + break; + } +#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 + default: + Q_ASSERT_X(false, "QCryptographicHash", "Method not compiled in"); + Q_UNREACHABLE(); + break; +#else case Md4: { md4_context copy = d->md4Context; d->result.resize(MD4_RESULTLEN); @@ -282,13 +379,6 @@ QByteArray QCryptographicHash::result() const MD5Final(©, (unsigned char *)d->result.data()); break; } - case Sha1: { - Sha1State copy = d->sha1Context; - d->result.resize(20); - sha1FinalizeState(©); - sha1ToHash(©, (unsigned char *)d->result.data()); - break; - } case Sha224: { SHA224Context copy = d->sha224Context; d->result.resize(SHA224HashSize); @@ -313,6 +403,31 @@ QByteArray QCryptographicHash::result() const SHA512Result(©, reinterpret_cast<unsigned char *>(d->result.data())); break; } + case Sha3_224: { + SHA3Context copy = d->sha3Context; + d->result.resize(224/8); + sha3Final(©, reinterpret_cast<BitSequence *>(d->result.data())); + break; + } + case Sha3_256: { + SHA3Context copy = d->sha3Context; + d->result.resize(256/8); + sha3Final(©, reinterpret_cast<BitSequence *>(d->result.data())); + break; + } + case Sha3_384: { + SHA3Context copy = d->sha3Context; + d->result.resize(384/8); + sha3Final(©, reinterpret_cast<BitSequence *>(d->result.data())); + break; + } + case Sha3_512: { + SHA3Context copy = d->sha3Context; + d->result.resize(512/8); + sha3Final(©, reinterpret_cast<BitSequence *>(d->result.data())); + break; + } +#endif } return d->result; } |