File indexing completed on 2024-04-28 04:44:08

0001 /**
0002  * Copyright (C)  2004-2006  Brad Hards <bradh@frogmouth.net>
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  *
0008  * 1. Redistributions of source code must retain the above copyright
0009  *   notice, this list of conditions and the following disclaimer.
0010  * 2. Redistributions in binary form must reproduce the above copyright
0011  *   notice, this list of conditions and the following disclaimer in the
0012  *   documentation and/or other materials provided with the distribution.
0013  *
0014  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0015  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0016  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0017  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0018  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0019  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0020  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0021  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0022  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0023  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0024  */
0025 
0026 #include <QFile>
0027 #include <QtCrypto>
0028 #include <QtTest/QtTest>
0029 
0030 #ifdef QT_STATICPLUGIN
0031 #include "import_plugins.h"
0032 #endif
0033 
0034 class HashUnitTest : public QObject
0035 {
0036     Q_OBJECT
0037 
0038 private Q_SLOTS:
0039     void initTestCase();
0040     void cleanupTestCase();
0041     void md2test_data();
0042     void md2test();
0043     void md4test_data();
0044     void md4test();
0045     void md5test_data();
0046     void md5test();
0047     void md5filetest();
0048     void sha0test_data();
0049     void sha0test();
0050     void sha0longtest();
0051     void sha1test_data();
0052     void sha1test();
0053     void sha1longtest();
0054     void sha224test_data();
0055     void sha224test();
0056     void sha224longtest();
0057     void sha256test_data();
0058     void sha256test();
0059     void sha256longtest();
0060     void sha384test_data();
0061     void sha384test();
0062     void sha384longtest();
0063     void sha512test_data();
0064     void sha512test();
0065     void sha512longtest();
0066     void rmd160test_data();
0067     void rmd160test();
0068     void rmd160longtest();
0069     void whirlpooltest_data();
0070     void whirlpooltest();
0071     void whirlpoollongtest();
0072 
0073 private:
0074     QCA::Initializer *m_init;
0075     QStringList       providersToTest;
0076 };
0077 
0078 void HashUnitTest::initTestCase()
0079 {
0080     m_init               = new QCA::Initializer;
0081     const auto providers = QCA::providers();
0082     for (QCA::Provider *provider : providers)
0083         providersToTest << provider->name();
0084     providersToTest << QCA::defaultProvider()->name();
0085 }
0086 
0087 void HashUnitTest::cleanupTestCase()
0088 {
0089     QCA::unloadAllPlugins();
0090     delete m_init;
0091 }
0092 
0093 void HashUnitTest::md2test_data()
0094 {
0095     // These are as specified in RFC 1319
0096     QTest::addColumn<QByteArray>("input");
0097     QTest::addColumn<QString>("expectedHash");
0098 
0099     QTest::newRow("md2()") << QByteArray("") << QStringLiteral("8350e5a3e24c153df2275c9f80692773");
0100     QTest::newRow("md2(a)") << QByteArray("a") << QStringLiteral("32ec01ec4a6dac72c0ab96fb34c0b5d1");
0101     QTest::newRow("md2(abc)") << QByteArray("abc") << QStringLiteral("da853b0d3f88d99b30283a69e6ded6bb");
0102     QTest::newRow("md2(messageDigest)") << QByteArray("message digest")
0103                                         << QStringLiteral("ab4f496bfb2a530b219ff33031fe06b0");
0104     QTest::newRow("md2([a-z])") << QByteArray("abcdefghijklmnopqrstuvwxyz")
0105                                 << QStringLiteral("4e8ddff3650292ab5a4108c3aa47940b");
0106     QTest::newRow("md2([A-z,0-9])") << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
0107                                     << QStringLiteral("da33def2a42df13975352846c30338cd");
0108     QTest::newRow("md2(nums)")
0109         << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
0110         << QStringLiteral("d5976f79d83d3a0dc9806c3c66f3efd8");
0111 }
0112 
0113 void HashUnitTest::md2test()
0114 {
0115     QFETCH(QByteArray, input);
0116     QFETCH(QString, expectedHash);
0117 
0118     bool anyProviderTested = false;
0119     foreach (QString provider, providersToTest) {
0120         if (QCA::isSupported("md2", provider)) {
0121             anyProviderTested = true;
0122 
0123             QCA::Hash hash = QCA::Hash(QStringLiteral("md2"), provider);
0124             QCA::Hash copy = hash;
0125             copy.context(); // detach
0126 
0127             QCOMPARE(hash.hashToString(input), expectedHash);
0128             QCOMPARE(copy.hashToString(input), expectedHash);
0129         }
0130     }
0131     if (!anyProviderTested)
0132         qWarning() << "NONE of the providers supports MD2:" << providersToTest;
0133 }
0134 
0135 void HashUnitTest::md4test_data()
0136 {
0137     // These are as specified in RFC 1320
0138     QTest::addColumn<QByteArray>("input");
0139     QTest::addColumn<QString>("expectedHash");
0140 
0141     QTest::newRow("md4()") << QByteArray("") << QStringLiteral("31d6cfe0d16ae931b73c59d7e0c089c0");
0142     QTest::newRow("md4(a)") << QByteArray("a") << QStringLiteral("bde52cb31de33e46245e05fbdbd6fb24");
0143     QTest::newRow("md4(abc)") << QByteArray("abc") << QStringLiteral("a448017aaf21d8525fc10ae87aa6729d");
0144     QTest::newRow("md4(messageDigest)") << QByteArray("message digest")
0145                                         << QStringLiteral("d9130a8164549fe818874806e1c7014b");
0146     QTest::newRow("md4([a-z])") << QByteArray("abcdefghijklmnopqrstuvwxyz")
0147                                 << QStringLiteral("d79e1c308aa5bbcdeea8ed63df412da9");
0148     QTest::newRow("md4([A-z,0-9])") << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
0149                                     << QStringLiteral("043f8582f241db351ce627e153e7f0e4");
0150     QTest::newRow("md4(nums)")
0151         << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
0152         << QStringLiteral("e33b4ddc9c38f2199c3e7b164fcc0536");
0153 }
0154 
0155 void HashUnitTest::md4test()
0156 {
0157     bool anyProviderTested = false;
0158     QFETCH(QByteArray, input);
0159     QFETCH(QString, expectedHash);
0160 
0161     foreach (QString provider, providersToTest) {
0162         if (QCA::isSupported("md4", provider)) {
0163             anyProviderTested = true;
0164 
0165             QCA::Hash hash = QCA::Hash(QStringLiteral("md4"), provider);
0166             QCA::Hash copy = hash;
0167             hash.context(); // detach
0168 
0169             QCOMPARE(hash.hashToString(input), expectedHash);
0170             QCOMPARE(copy.hashToString(input), expectedHash);
0171         }
0172     }
0173     if (!anyProviderTested)
0174         qWarning() << "NONE of the providers supports MD4:" << providersToTest;
0175 }
0176 
0177 void HashUnitTest::md5test_data()
0178 {
0179     // These are as specified in RFC 1321
0180     // They also match Australian Standard (AS) 2805.1.3.2-2000 Appendix A
0181     QTest::addColumn<QByteArray>("input");
0182     QTest::addColumn<QString>("expectedHash");
0183 
0184     QTest::newRow("md5()") << QByteArray("") << QStringLiteral("d41d8cd98f00b204e9800998ecf8427e");
0185     QTest::newRow("md5(a)") << QByteArray("a") << QStringLiteral("0cc175b9c0f1b6a831c399e269772661");
0186     QTest::newRow("md5(abc)") << QByteArray("abc") << QStringLiteral("900150983cd24fb0d6963f7d28e17f72");
0187     QTest::newRow("md5(messageDigest)") << QByteArray("message digest")
0188                                         << QStringLiteral("f96b697d7cb7938d525a2f31aaf161d0");
0189     QTest::newRow("md5([a-z])") << QByteArray("abcdefghijklmnopqrstuvwxyz")
0190                                 << QStringLiteral("c3fcd3d76192e4007dfb496cca67e13b");
0191     QTest::newRow("md5([A-z,0-9])") << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
0192                                     << QStringLiteral("d174ab98d277d9f5a5611c2c9f419d9f");
0193     QTest::newRow("md5(nums)")
0194         << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
0195         << QStringLiteral("57edf4a22be3c955ac49da2e2107b67a");
0196 }
0197 
0198 void HashUnitTest::md5test()
0199 {
0200     bool anyProviderTested = false;
0201     QFETCH(QByteArray, input);
0202     QFETCH(QString, expectedHash);
0203 
0204     foreach (QString provider, providersToTest) {
0205         if (QCA::isSupported("md5", provider)) {
0206             anyProviderTested = true;
0207 
0208             QCA::Hash hash = QCA::Hash(QStringLiteral("md5"), provider);
0209             QCA::Hash copy = hash;
0210             hash.context(); // detach
0211 
0212             QCOMPARE(hash.hashToString(input), expectedHash);
0213             QCOMPARE(copy.hashToString(input), expectedHash);
0214         }
0215     }
0216     if (!anyProviderTested)
0217         qWarning() << "NONE of the providers supports MD2:" << providersToTest;
0218 }
0219 
0220 void HashUnitTest::md5filetest()
0221 {
0222     foreach (QString provider, providersToTest) {
0223         if (!QCA::isSupported("md5", provider)) {
0224             QFile f1(QStringLiteral(TEST_DATA_DIR "/data/empty"));
0225             QVERIFY(f1.open(QIODevice::ReadOnly));
0226             {
0227                 QCA::Hash hashObj(QStringLiteral("md5"), provider);
0228                 hashObj.update(&f1);
0229                 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
0230                          QStringLiteral("d41d8cd98f00b204e9800998ecf8427e"));
0231             }
0232 
0233             QFile f2(QStringLiteral(TEST_DATA_DIR "/data/twobytes"));
0234             QVERIFY(f2.open(QIODevice::ReadOnly));
0235             {
0236                 QCA::Hash hashObj(QStringLiteral("md5"), provider);
0237                 hashObj.update(&f2);
0238                 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
0239                          QStringLiteral("5fc9808ed18e442ab4164c59f151e757"));
0240             }
0241 
0242             QFile f3(QStringLiteral(TEST_DATA_DIR "/data/twohundredbytes"));
0243             QVERIFY(f3.open(QIODevice::ReadOnly));
0244             {
0245                 QCA::Hash hashObj(QStringLiteral("md5"), provider);
0246                 hashObj.update(&f3);
0247                 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
0248                          QStringLiteral("b91c1f114d942520ecdf7e84e580cda3"));
0249             }
0250         }
0251     }
0252 }
0253 
0254 void HashUnitTest::sha0test_data()
0255 {
0256     // These are extracted from OpenOffice.org 1.1.2, in sal/workben/t_digest.c
0257     // Check FIPS 180-1?
0258     QTest::addColumn<QByteArray>("input");
0259     QTest::addColumn<QString>("expectedHash");
0260 
0261     QTest::newRow("sha0(abc)") << QByteArray("abc") << QStringLiteral("0164b8a914cd2a5e74c4f7ff082c4d97f1edf880");
0262     QTest::newRow("sha0(abc)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
0263                                << QStringLiteral("d2516ee1acfa5baf33dfc1c471e438449ef134c8");
0264 }
0265 
0266 void HashUnitTest::sha0test()
0267 {
0268     bool anyProviderTested = false;
0269     QFETCH(QByteArray, input);
0270     QFETCH(QString, expectedHash);
0271 
0272     foreach (QString provider, providersToTest) {
0273         if (QCA::isSupported("sha0", provider)) {
0274             anyProviderTested = true;
0275 
0276             QCA::Hash hash = QCA::Hash(QStringLiteral("sha0"), provider);
0277             QCA::Hash copy = hash;
0278             hash.context(); // detach
0279 
0280             QCOMPARE(hash.hashToString(input), expectedHash);
0281             QCOMPARE(copy.hashToString(input), expectedHash);
0282         }
0283     }
0284     if (!anyProviderTested)
0285         qWarning() << "NONE of the providers supports SHA0:" << providersToTest;
0286 }
0287 
0288 void HashUnitTest::sha0longtest()
0289 {
0290     QByteArray fillerString;
0291     fillerString.fill('a', 1000);
0292 
0293     // This test extracted from OpenOffice.org 1.1.2, in sal/workben/t_digest.c
0294 
0295     foreach (QString provider, providersToTest) {
0296         if (QCA::isSupported("sha0", provider)) {
0297             QCA::Hash shaHash(QStringLiteral("sha0"), provider);
0298             for (int i = 0; i < 1000; i++)
0299                 shaHash.update(fillerString);
0300             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0301                      QStringLiteral("3232affa48628a26653b5aaa44541fd90d690603"));
0302 
0303             shaHash.clear();
0304             for (int i = 0; i < 1000; i++)
0305                 shaHash.update(fillerString);
0306             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0307                      QStringLiteral("3232affa48628a26653b5aaa44541fd90d690603"));
0308         }
0309     }
0310 }
0311 
0312 void HashUnitTest::sha1test_data()
0313 {
0314     // These are as specified in FIPS 180-2. Matches RFC3174
0315     // Some additions from Australian Standard (AS) 2805.13.3-2000
0316     QTest::addColumn<QByteArray>("input");
0317     QTest::addColumn<QString>("expectedHash");
0318 
0319     // FIPS 180-2, Appendix A.1
0320     QTest::newRow("sha1(abc)") << QByteArray("abc") << QStringLiteral("a9993e364706816aba3e25717850c26c9cd0d89d");
0321 
0322     // FIPS 180-2, Appendix A.2
0323     QTest::newRow("sha1(a-q)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
0324                                << QStringLiteral("84983e441c3bd26ebaae4aa1f95129e5e54670f1");
0325 
0326     // AS 2805.13.3-200 Appendix A
0327     // also has some duplicates from FIPS 180-2
0328     QTest::newRow("sha1()") << QByteArray("") << QStringLiteral("da39a3ee5e6b4b0d3255bfef95601890afd80709");
0329     QTest::newRow("sha1(a)") << QByteArray("a") << QStringLiteral("86f7e437faa5a7fce15d1ddcb9eaeaea377667b8");
0330     QTest::newRow("sha1(a-z)") << QByteArray("abcdefghijklmnopqrstuvwxyz")
0331                                << QStringLiteral("32d10c7b8cf96570ca04ce37f2a19d84240d3a89");
0332 }
0333 
0334 void HashUnitTest::sha1test()
0335 {
0336     bool anyProviderTested = false;
0337     QFETCH(QByteArray, input);
0338     QFETCH(QString, expectedHash);
0339 
0340     foreach (QString provider, providersToTest) {
0341         if (QCA::isSupported("sha1", provider)) {
0342             anyProviderTested = true;
0343 
0344             QCA::Hash hash = QCA::Hash(QStringLiteral("sha1"), provider);
0345             QCA::Hash copy = hash;
0346             hash.context(); // detach
0347 
0348             QCOMPARE(hash.hashToString(input), expectedHash);
0349             QCOMPARE(copy.hashToString(input), expectedHash);
0350         }
0351     }
0352     if (!anyProviderTested)
0353         qWarning() << "NONE of the providers supports SHA1:" << providersToTest;
0354 }
0355 
0356 void HashUnitTest::sha1longtest()
0357 {
0358     foreach (QString provider, providersToTest) {
0359         if (QCA::isSupported("sha1", provider)) {
0360             // QTime t;
0361             // t.start();
0362             QByteArray fillerString;
0363             fillerString.fill('a', 1000);
0364 
0365             // This test extracted from OpenOffice.org 1.1.2, in sal/workben/t_digest.c
0366             // It basically reflects FIPS 180-2, Appendix A.3
0367             // Also as per AS 2805.13.3-2000 Appendix A
0368             QCA::Hash shaHash(QStringLiteral("sha1"), provider);
0369             for (int i = 0; i < 1000; i++)
0370                 shaHash.update(fillerString);
0371             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0372                      QStringLiteral("34aa973cd4c4daa4f61eeb2bdbad27316534016f"));
0373 
0374             QFile f1(QStringLiteral(TEST_DATA_DIR "/data/empty"));
0375             QVERIFY(f1.open(QIODevice::ReadOnly));
0376             {
0377                 QCA::Hash hashObj(QStringLiteral("sha1"), provider);
0378                 hashObj.update(&f1);
0379                 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
0380                          QStringLiteral("da39a3ee5e6b4b0d3255bfef95601890afd80709"));
0381             }
0382 
0383             QFile f2(QStringLiteral(TEST_DATA_DIR "/data/twobytes"));
0384             QVERIFY(f2.open(QIODevice::ReadOnly));
0385             {
0386                 QCA::Hash hashObj(QStringLiteral("sha1"), provider);
0387                 hashObj.update(&f2);
0388                 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
0389                          QStringLiteral("efbd6de3c51ca16094391e837bf52f7452593e5c"));
0390             }
0391 
0392             QFile f3(QStringLiteral(TEST_DATA_DIR "/data/twohundredbytes"));
0393             QVERIFY(f3.open(QIODevice::ReadOnly));
0394             {
0395                 QCA::Hash hashObj(QStringLiteral("sha1"), provider);
0396                 hashObj.update(&f3);
0397                 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
0398                          QStringLiteral("d636519dfb18d913acbe69fc3ee5a4c7ac870297"));
0399             }
0400         }
0401     }
0402 }
0403 
0404 void HashUnitTest::sha224test_data()
0405 {
0406     QTest::addColumn<QByteArray>("input");
0407     QTest::addColumn<QString>("expectedHash");
0408 
0409     // These are as specified in FIPS 180-2, change notice 1
0410 
0411     // FIPS 180-2, Appendix B.1
0412     QTest::newRow("sha224(abc)") << QByteArray("abc")
0413                                  << QStringLiteral("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7");
0414 
0415     // FIPS 180-2, Appendix B.2
0416     QTest::newRow("sha224(aq)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
0417                                 << QStringLiteral("75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525");
0418 }
0419 
0420 void HashUnitTest::sha224test()
0421 {
0422     bool anyProviderTested = false;
0423     QFETCH(QByteArray, input);
0424     QFETCH(QString, expectedHash);
0425 
0426     foreach (QString provider, providersToTest) {
0427         if (QCA::isSupported("sha224", provider)) {
0428             anyProviderTested = true;
0429 
0430             QCA::Hash hash = QCA::Hash(QStringLiteral("sha224"), provider);
0431             QCA::Hash copy = hash;
0432             hash.context(); // detach
0433 
0434             QCOMPARE(hash.hashToString(input), expectedHash);
0435             QCOMPARE(copy.hashToString(input), expectedHash);
0436         }
0437     }
0438     if (!anyProviderTested)
0439         qWarning() << "NONE of the providers supports SHA224:" << providersToTest;
0440 }
0441 
0442 void HashUnitTest::sha224longtest()
0443 {
0444     QByteArray fillerString;
0445     fillerString.fill('a', 1000);
0446 
0447     foreach (QString provider, providersToTest) {
0448         if (QCA::isSupported("sha224", provider)) {
0449             QCA::Hash shaHash(QStringLiteral("sha224"), provider);
0450 
0451             // This basically reflects FIPS 180-2, change notice 1, section 3
0452             for (int i = 0; i < 1000; i++)
0453                 shaHash.update(fillerString);
0454             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0455                      QStringLiteral("20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"));
0456 
0457             shaHash.clear();
0458             for (int i = 0; i < 1000; i++)
0459                 shaHash.update(fillerString);
0460             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0461                      QStringLiteral("20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"));
0462         }
0463     }
0464 }
0465 
0466 void HashUnitTest::sha256test_data()
0467 {
0468     QTest::addColumn<QByteArray>("input");
0469     QTest::addColumn<QString>("expectedHash");
0470 
0471     // These are as specified in FIPS 180-2
0472 
0473     // FIPS 180-2, Appendix B.1
0474     QTest::newRow("sha256(abc)") << QByteArray("abc")
0475                                  << QStringLiteral("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
0476 
0477     // FIPS 180-2, Appendix B.2
0478     QTest::newRow("sha256(abc)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
0479                                  << QStringLiteral("248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
0480 }
0481 
0482 void HashUnitTest::sha256test()
0483 {
0484     bool anyProviderTested = false;
0485     QFETCH(QByteArray, input);
0486     QFETCH(QString, expectedHash);
0487 
0488     foreach (QString provider, providersToTest) {
0489         if (QCA::isSupported("sha256", provider)) {
0490             anyProviderTested = true;
0491 
0492             QCA::Hash hash = QCA::Hash(QStringLiteral("sha256"), provider);
0493             QCA::Hash copy = hash;
0494             hash.context(); // detach
0495 
0496             QCOMPARE(hash.hashToString(input), expectedHash);
0497             QCOMPARE(copy.hashToString(input), expectedHash);
0498         }
0499     }
0500     if (!anyProviderTested)
0501         qWarning() << "NONE of the providers supports SHA256:" << providersToTest;
0502 }
0503 
0504 void HashUnitTest::sha256longtest()
0505 {
0506     QByteArray fillerString;
0507     fillerString.fill('a', 1000);
0508 
0509     foreach (QString provider, providersToTest) {
0510         if (QCA::isSupported("sha256", provider)) {
0511             QCA::Hash shaHash(QStringLiteral("sha256"), provider);
0512 
0513             // This basically reflects FIPS 180-2, change notice 1, section 3
0514             for (int i = 0; i < 1000; i++)
0515                 shaHash.update(fillerString);
0516             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0517                      QStringLiteral("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"));
0518 
0519             shaHash.clear();
0520             for (int i = 0; i < 1000; i++)
0521                 shaHash.update(fillerString);
0522             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0523                      QStringLiteral("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"));
0524         }
0525     }
0526 }
0527 
0528 void HashUnitTest::sha384test_data()
0529 {
0530     QTest::addColumn<QByteArray>("input");
0531     QTest::addColumn<QString>("expectedHash");
0532 
0533     // These are as specified in FIPS 180-2, and from Aaron Gifford's SHA2 tests
0534 
0535     // FIPS 180-2, Appendix B.1
0536     QTest::newRow("sha384(abc)")
0537         << QByteArray("abc")
0538         << QStringLiteral(
0539                "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7");
0540 
0541     // FIPS 180-2, Appendix B.2
0542     QTest::newRow("sha384(a-u)")
0543         << QByteArray(
0544                "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrs"
0545                "tnopqrstu")
0546         << QStringLiteral(
0547                "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039");
0548 
0549     // Aaron Gifford, vector002.info
0550     QTest::newRow("sha384(a-q)")
0551         << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
0552         << QStringLiteral(
0553                "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b");
0554 }
0555 
0556 void HashUnitTest::sha384test()
0557 {
0558     bool anyProviderTested = false;
0559     QFETCH(QByteArray, input);
0560     QFETCH(QString, expectedHash);
0561 
0562     foreach (QString provider, providersToTest) {
0563         if (QCA::isSupported("sha384", provider)) {
0564             anyProviderTested = true;
0565 
0566             QCA::Hash hash = QCA::Hash(QStringLiteral("sha384"), provider);
0567             QCA::Hash copy = hash;
0568             hash.context(); // detach
0569 
0570             QCOMPARE(hash.hashToString(input), expectedHash);
0571             QCOMPARE(copy.hashToString(input), expectedHash);
0572         }
0573     }
0574     if (!anyProviderTested)
0575         qWarning() << "NONE of the providers supports SHA384:" << providersToTest;
0576 }
0577 
0578 void HashUnitTest::sha384longtest()
0579 {
0580     QByteArray fillerString;
0581     fillerString.fill('a', 1000);
0582 
0583     foreach (QString provider, providersToTest) {
0584         if (QCA::isSupported("sha384", provider)) {
0585             // QTime t;
0586             // t.start();
0587             QCA::Hash shaHash(QStringLiteral("sha384"), provider);
0588 
0589             // This basically reflects FIPS 180-2, change notice 1, section 3
0590             for (int i = 0; i < 1000; i++)
0591                 shaHash.update(fillerString);
0592             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0593                      QStringLiteral("9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae"
0594                                     "97ddd87f3d8985"));
0595 
0596             shaHash.clear();
0597             for (int i = 0; i < 1000; i++)
0598                 shaHash.update(fillerString);
0599             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0600                      QStringLiteral("9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae"
0601                                     "97ddd87f3d8985"));
0602             // qDebug() << "SHA384: " << provider << " elapsed " << t.elapsed();
0603         }
0604     }
0605 }
0606 
0607 // These are as specified in FIPS 180-2, and from Aaron Gifford's SHA2 tests
0608 void HashUnitTest::sha512test_data()
0609 {
0610     QTest::addColumn<QByteArray>("input");
0611     QTest::addColumn<QString>("expectedHash");
0612 
0613     // FIPS 180-2, Appendix C.1
0614     QTest::newRow("sha512(abc)") << QByteArray("abc")
0615                                  << QStringLiteral(
0616                                         "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1"
0617                                         "a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
0618     // FIPS 180-2, Appendix C.2
0619     QTest::newRow("sha512(a-u)") << QByteArray(
0620                                         "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmno"
0621                                         "pqklmnopqrlmnopqrsmnopqrstnopqrstu")
0622                                  << QStringLiteral(
0623                                         "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7"
0624                                         "e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909");
0625 
0626     // Aaron Gifford, vector002.info
0627     QTest::newRow("sha512(a-q)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
0628                                  << QStringLiteral(
0629                                         "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07"
0630                                         "f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445");
0631 }
0632 
0633 void HashUnitTest::sha512test()
0634 {
0635     bool anyProviderTested = false;
0636     QFETCH(QByteArray, input);
0637     QFETCH(QString, expectedHash);
0638 
0639     foreach (QString provider, providersToTest) {
0640         if (QCA::isSupported("sha512", provider)) {
0641             anyProviderTested = true;
0642 
0643             QCA::Hash hash = QCA::Hash(QStringLiteral("sha512"), provider);
0644             QCA::Hash copy = hash;
0645             hash.context(); // detach
0646 
0647             QCOMPARE(hash.hashToString(input), expectedHash);
0648             QCOMPARE(copy.hashToString(input), expectedHash);
0649         }
0650     }
0651     if (!anyProviderTested)
0652         qWarning() << "NONE of the providers supports SHA512:" << providersToTest;
0653 }
0654 
0655 void HashUnitTest::sha512longtest()
0656 {
0657     QByteArray fillerString;
0658     fillerString.fill('a', 1000);
0659 
0660     foreach (QString provider, providersToTest) {
0661         if (QCA::isSupported("sha512", provider)) {
0662             QCA::Hash shaHash(QStringLiteral("sha512"), provider);
0663 
0664             // This basically reflects FIPS 180-2, change notice 1, section 3
0665             for (int i = 0; i < 1000; i++)
0666                 shaHash.update(fillerString);
0667             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0668                      QStringLiteral("e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4c"
0669                                     "b0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"));
0670 
0671             shaHash.clear();
0672             for (int i = 0; i < 1000; i++)
0673                 shaHash.update(fillerString);
0674             QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
0675                      QStringLiteral("e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4c"
0676                                     "b0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"));
0677         }
0678     }
0679 }
0680 
0681 // These are as specified in http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
0682 // ISO/IEC 10118-3 costs a bit of money.
0683 void HashUnitTest::rmd160test_data()
0684 {
0685     QTest::addColumn<QByteArray>("input");
0686     QTest::addColumn<QString>("expectedHash");
0687 
0688     QTest::newRow("rmd160()") << QByteArray("") << QStringLiteral("9c1185a5c5e9fc54612808977ee8f548b2258d31");
0689     QTest::newRow("rmd160(a)") << QByteArray("a") << QStringLiteral("0bdc9d2d256b3ee9daae347be6f4dc835a467ffe");
0690     QTest::newRow("rmd160(abc)") << QByteArray("abc") << QStringLiteral("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
0691     QTest::newRow("rmd160(md)") << QByteArray("message digest")
0692                                 << QStringLiteral("5d0689ef49d2fae572b881b123a85ffa21595f36");
0693     QTest::newRow("rmd160(a-z)") << QByteArray("abcdefghijklmnopqrstuvwxyz")
0694                                  << QStringLiteral("f71c27109c692c1b56bbdceb5b9d2865b3708dbc");
0695     QTest::newRow("rmd160(a-q)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
0696                                  << QStringLiteral("12a053384a9c0c88e405a06c27dcf49ada62eb2b");
0697     QTest::newRow("rmd160(A-9)") << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
0698                                  << QStringLiteral("b0e20b6e3116640286ed3a87a5713079b21f5189");
0699     QTest::newRow("rmd160(1-0)")
0700         << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
0701         << QStringLiteral("9b752e45573d4b39f4dbd3323cab82bf63326bfb");
0702 }
0703 
0704 void HashUnitTest::rmd160test()
0705 {
0706     bool anyProviderTested = false;
0707     QFETCH(QByteArray, input);
0708     QFETCH(QString, expectedHash);
0709 
0710     foreach (QString provider, providersToTest) {
0711         if (QCA::isSupported("ripemd160", provider)) {
0712             anyProviderTested = true;
0713 
0714             QCA::Hash hash = QCA::Hash(QStringLiteral("ripemd160"), provider);
0715             QCA::Hash copy = hash;
0716             hash.context(); // detach
0717 
0718             QCOMPARE(hash.hashToString(input), expectedHash);
0719             QCOMPARE(copy.hashToString(input), expectedHash);
0720         }
0721     }
0722     if (!anyProviderTested)
0723         qWarning() << "NONE of the providers supports RIPEMD160:" << providersToTest;
0724 }
0725 
0726 void HashUnitTest::rmd160longtest()
0727 {
0728     QByteArray fillerString;
0729     fillerString.fill('a', 1000);
0730 
0731     foreach (QString provider, providersToTest) {
0732         if (QCA::isSupported("ripemd160", provider)) {
0733             QCA::Hash rmdHash(QStringLiteral("ripemd160"), provider);
0734 
0735             // This is the "million times 'a' test"
0736             for (int i = 0; i < 1000; i++)
0737                 rmdHash.update(fillerString);
0738             QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
0739                      QStringLiteral("52783243c1697bdbe16d37f97f68f08325dc1528"));
0740 
0741             rmdHash.clear();
0742             for (int i = 0; i < 1000; i++)
0743                 rmdHash.update(fillerString);
0744             QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
0745                      QStringLiteral("52783243c1697bdbe16d37f97f68f08325dc1528"));
0746 
0747             // This is the "8 rounds of 1234567890" test.
0748             // It also ensure that we can re-use hash objects correctly.
0749             static char bindata[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30};
0750             QByteArray  fillerArray(bindata, sizeof(bindata)); // "1234567890"
0751             rmdHash.clear();
0752             for (int i = 0; i < 8; i++)
0753                 rmdHash.update(fillerArray);
0754             QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
0755                      QStringLiteral("9b752e45573d4b39f4dbd3323cab82bf63326bfb"));
0756         }
0757     }
0758 }
0759 
0760 // These are from the documentation pack at http://paginas.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html
0761 void HashUnitTest::whirlpooltest_data()
0762 {
0763     QTest::addColumn<QByteArray>("input");
0764     QTest::addColumn<QString>("expectedHash");
0765 
0766     QTest::newRow("whirlpool()") << QByteArray("")
0767                                  << QStringLiteral(
0768                                         "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288f"
0769                                         "ebcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3");
0770     QTest::newRow("whirlpool(a)") << QByteArray("a")
0771                                   << QStringLiteral(
0772                                          "8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413ae"
0773                                          "ff63a42391a39145a591a92200d560195e53b478584fdae231a");
0774     QTest::newRow("whirlpool(abc)") << QByteArray("abc")
0775                                     << QStringLiteral(
0776                                            "4e2448a4c6f486bb16b6562c73b4020bf3043e3a731bce721ae1b303d97e6d4c7181eebdb6c"
0777                                            "57e277d0e34957114cbd6c797fc9d95d8b582d225292076d4eef5");
0778     QTest::newRow("whirlpool(md)") << QByteArray("message digest")
0779                                    << QStringLiteral(
0780                                           "378c84a4126e2dc6e56dcc7458377aac838d00032230f53ce1f5700c0ffb4d3b8421557659ef"
0781                                           "55c106b4b52ac5a4aaa692ed920052838f3362e86dbd37a8903e");
0782     QTest::newRow("whirlpool(a-k)") << QByteArray("abcdbcdecdefdefgefghfghighijhijk")
0783                                     << QStringLiteral(
0784                                            "2a987ea40f917061f5d6f0a0e4644f488a7a5a52deee656207c562f988e95c6916bdc8031bc"
0785                                            "5be1b7b947639fe050b56939baaa0adff9ae6745b7b181c3be3fd");
0786     QTest::newRow("whirlpool(a-z)") << QByteArray("abcdefghijklmnopqrstuvwxyz")
0787                                     << QStringLiteral(
0788                                            "f1d754662636ffe92c82ebb9212a484a8d38631ead4238f5442ee13b8054e41b08bf2a9251c"
0789                                            "30b6a0b8aae86177ab4a6f68f673e7207865d5d9819a3dba4eb3b");
0790     QTest::newRow("whirlpool(A-9)") << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
0791                                     << QStringLiteral(
0792                                            "dc37e008cf9ee69bf11f00ed9aba26901dd7c28cdec066cc6af42e40f82f3a1e08eba266291"
0793                                            "29d8fb7cb57211b9281a65517cc879d7b962142c65f5a7af01467");
0794     QTest::newRow("whirlpool(1-0)")
0795         << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
0796         << QStringLiteral(
0797                "466ef18babb0154d25b9d38a6414f5c08784372bccb204d6549c4afadb6014294d5bd8df2a6c44e538cd047b2681a51a2c60481"
0798                "e88c5a20b2c2a80cf3a9a083b");
0799 }
0800 
0801 void HashUnitTest::whirlpooltest()
0802 {
0803     bool anyProviderTested = false;
0804     QFETCH(QByteArray, input);
0805     QFETCH(QString, expectedHash);
0806 
0807     foreach (QString provider, providersToTest) {
0808         if (QCA::isSupported("whirlpool", provider)) {
0809             anyProviderTested = true;
0810 
0811             QCA::Hash hash = QCA::Hash(QStringLiteral("whirlpool"), provider);
0812             QCA::Hash copy = hash;
0813             hash.context(); // detach
0814 
0815             QCOMPARE(hash.hashToString(input), expectedHash);
0816             QCOMPARE(copy.hashToString(input), expectedHash);
0817         }
0818     }
0819     if (!anyProviderTested)
0820         qWarning() << "NONE of the providers supports Whirlpool:" << providersToTest;
0821 }
0822 
0823 void HashUnitTest::whirlpoollongtest()
0824 {
0825     QByteArray fillerString;
0826     fillerString.fill('a', 1000);
0827 
0828     foreach (QString provider, providersToTest) {
0829         if (QCA::isSupported("whirlpool", provider)) {
0830             QCA::Hash rmdHash(QStringLiteral("whirlpool"), provider);
0831 
0832             // This is the "million times 'a' test"
0833             for (int i = 0; i < 1000; i++)
0834                 rmdHash.update(fillerString);
0835             QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
0836                      QStringLiteral("0c99005beb57eff50a7cf005560ddf5d29057fd86b20bfd62deca0f1ccea4af51fc15490eddc47af32"
0837                                     "bb2b66c34ff9ad8c6008ad677f77126953b226e4ed8b01"));
0838 
0839             rmdHash.clear();
0840             for (int i = 0; i < 1000; i++)
0841                 rmdHash.update(fillerString);
0842             QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
0843                      QStringLiteral("0c99005beb57eff50a7cf005560ddf5d29057fd86b20bfd62deca0f1ccea4af51fc15490eddc47af32"
0844                                     "bb2b66c34ff9ad8c6008ad677f77126953b226e4ed8b01"));
0845 
0846             // This is the "8 rounds of 1234567890" test.
0847             // It also ensure that we can re-use hash objects correctly.
0848             static char bindata[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30};
0849             QByteArray  fillerArray(bindata, sizeof(bindata)); // "1234567890"
0850             rmdHash.clear();
0851             for (int i = 0; i < 8; i++)
0852                 rmdHash.update(fillerArray);
0853             QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
0854                      QStringLiteral("466ef18babb0154d25b9d38a6414f5c08784372bccb204d6549c4afadb6014294d5bd8df2a6c44e538"
0855                                     "cd047b2681a51a2c60481e88c5a20b2c2a80cf3a9a083b"));
0856         }
0857     }
0858 }
0859 
0860 QTEST_MAIN(HashUnitTest)
0861 
0862 #include "hashunittest.moc"