1 | /** |
2 | * Copyright (C) 2004-2006 Brad Hards <bradh@frogmouth.net> |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * |
8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * 2. Redistributions in binary form must reproduce the above copyright |
11 | * notice, this list of conditions and the following disclaimer in the |
12 | * documentation and/or other materials provided with the distribution. |
13 | * |
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
17 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include <QFile> |
27 | #include <QtCrypto> |
28 | #include <QtTest/QtTest> |
29 | |
30 | #ifdef QT_STATICPLUGIN |
31 | #include "import_plugins.h" |
32 | #endif |
33 | |
34 | class HashUnitTest : public QObject |
35 | { |
36 | Q_OBJECT |
37 | |
38 | private Q_SLOTS: |
39 | void initTestCase(); |
40 | void cleanupTestCase(); |
41 | void md2test_data(); |
42 | void md2test(); |
43 | void md4test_data(); |
44 | void md4test(); |
45 | void md5test_data(); |
46 | void md5test(); |
47 | void md5filetest(); |
48 | void sha0test_data(); |
49 | void sha0test(); |
50 | void sha0longtest(); |
51 | void sha1test_data(); |
52 | void sha1test(); |
53 | void sha1longtest(); |
54 | void sha224test_data(); |
55 | void sha224test(); |
56 | void sha224longtest(); |
57 | void sha256test_data(); |
58 | void sha256test(); |
59 | void sha256longtest(); |
60 | void sha384test_data(); |
61 | void sha384test(); |
62 | void sha384longtest(); |
63 | void sha512test_data(); |
64 | void sha512test(); |
65 | void sha512longtest(); |
66 | void rmd160test_data(); |
67 | void rmd160test(); |
68 | void rmd160longtest(); |
69 | void whirlpooltest_data(); |
70 | void whirlpooltest(); |
71 | void whirlpoollongtest(); |
72 | |
73 | private: |
74 | QCA::Initializer *m_init; |
75 | QStringList providersToTest; |
76 | }; |
77 | |
78 | void HashUnitTest::initTestCase() |
79 | { |
80 | m_init = new QCA::Initializer; |
81 | const auto providers = QCA::providers(); |
82 | for (QCA::Provider *provider : providers) |
83 | providersToTest << provider->name(); |
84 | providersToTest << QCA::defaultProvider()->name(); |
85 | } |
86 | |
87 | void HashUnitTest::cleanupTestCase() |
88 | { |
89 | QCA::unloadAllPlugins(); |
90 | delete m_init; |
91 | } |
92 | |
93 | void HashUnitTest::md2test_data() |
94 | { |
95 | // These are as specified in RFC 1319 |
96 | QTest::addColumn<QByteArray>(name: "input" ); |
97 | QTest::addColumn<QString>(name: "expectedHash" ); |
98 | |
99 | QTest::newRow(dataTag: "md2()" ) << QByteArray("" ) << QStringLiteral("8350e5a3e24c153df2275c9f80692773" ); |
100 | QTest::newRow(dataTag: "md2(a)" ) << QByteArray("a" ) << QStringLiteral("32ec01ec4a6dac72c0ab96fb34c0b5d1" ); |
101 | QTest::newRow(dataTag: "md2(abc)" ) << QByteArray("abc" ) << QStringLiteral("da853b0d3f88d99b30283a69e6ded6bb" ); |
102 | QTest::newRow(dataTag: "md2(messageDigest)" ) << QByteArray("message digest" ) |
103 | << QStringLiteral("ab4f496bfb2a530b219ff33031fe06b0" ); |
104 | QTest::newRow(dataTag: "md2([a-z])" ) << QByteArray("abcdefghijklmnopqrstuvwxyz" ) |
105 | << QStringLiteral("4e8ddff3650292ab5a4108c3aa47940b" ); |
106 | QTest::newRow(dataTag: "md2([A-z,0-9])" ) << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) |
107 | << QStringLiteral("da33def2a42df13975352846c30338cd" ); |
108 | QTest::newRow(dataTag: "md2(nums)" ) |
109 | << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890" ) |
110 | << QStringLiteral("d5976f79d83d3a0dc9806c3c66f3efd8" ); |
111 | } |
112 | |
113 | void HashUnitTest::md2test() |
114 | { |
115 | QFETCH(QByteArray, input); |
116 | QFETCH(QString, expectedHash); |
117 | |
118 | bool anyProviderTested = false; |
119 | foreach (QString provider, providersToTest) { |
120 | if (QCA::isSupported(features: "md2" , provider)) { |
121 | anyProviderTested = true; |
122 | |
123 | QCA::Hash hash = QCA::Hash(QStringLiteral("md2" ), provider); |
124 | QCA::Hash copy = hash; |
125 | copy.context(); // detach |
126 | |
127 | QCOMPARE(hash.hashToString(input), expectedHash); |
128 | QCOMPARE(copy.hashToString(input), expectedHash); |
129 | } |
130 | } |
131 | if (!anyProviderTested) |
132 | qWarning() << "NONE of the providers supports MD2:" << providersToTest; |
133 | } |
134 | |
135 | void HashUnitTest::md4test_data() |
136 | { |
137 | // These are as specified in RFC 1320 |
138 | QTest::addColumn<QByteArray>(name: "input" ); |
139 | QTest::addColumn<QString>(name: "expectedHash" ); |
140 | |
141 | QTest::newRow(dataTag: "md4()" ) << QByteArray("" ) << QStringLiteral("31d6cfe0d16ae931b73c59d7e0c089c0" ); |
142 | QTest::newRow(dataTag: "md4(a)" ) << QByteArray("a" ) << QStringLiteral("bde52cb31de33e46245e05fbdbd6fb24" ); |
143 | QTest::newRow(dataTag: "md4(abc)" ) << QByteArray("abc" ) << QStringLiteral("a448017aaf21d8525fc10ae87aa6729d" ); |
144 | QTest::newRow(dataTag: "md4(messageDigest)" ) << QByteArray("message digest" ) |
145 | << QStringLiteral("d9130a8164549fe818874806e1c7014b" ); |
146 | QTest::newRow(dataTag: "md4([a-z])" ) << QByteArray("abcdefghijklmnopqrstuvwxyz" ) |
147 | << QStringLiteral("d79e1c308aa5bbcdeea8ed63df412da9" ); |
148 | QTest::newRow(dataTag: "md4([A-z,0-9])" ) << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) |
149 | << QStringLiteral("043f8582f241db351ce627e153e7f0e4" ); |
150 | QTest::newRow(dataTag: "md4(nums)" ) |
151 | << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890" ) |
152 | << QStringLiteral("e33b4ddc9c38f2199c3e7b164fcc0536" ); |
153 | } |
154 | |
155 | void HashUnitTest::md4test() |
156 | { |
157 | bool anyProviderTested = false; |
158 | QFETCH(QByteArray, input); |
159 | QFETCH(QString, expectedHash); |
160 | |
161 | foreach (QString provider, providersToTest) { |
162 | if (QCA::isSupported(features: "md4" , provider)) { |
163 | anyProviderTested = true; |
164 | |
165 | QCA::Hash hash = QCA::Hash(QStringLiteral("md4" ), provider); |
166 | QCA::Hash copy = hash; |
167 | hash.context(); // detach |
168 | |
169 | QCOMPARE(hash.hashToString(input), expectedHash); |
170 | QCOMPARE(copy.hashToString(input), expectedHash); |
171 | } |
172 | } |
173 | if (!anyProviderTested) |
174 | qWarning() << "NONE of the providers supports MD4:" << providersToTest; |
175 | } |
176 | |
177 | void HashUnitTest::md5test_data() |
178 | { |
179 | // These are as specified in RFC 1321 |
180 | // They also match Australian Standard (AS) 2805.1.3.2-2000 Appendix A |
181 | QTest::addColumn<QByteArray>(name: "input" ); |
182 | QTest::addColumn<QString>(name: "expectedHash" ); |
183 | |
184 | QTest::newRow(dataTag: "md5()" ) << QByteArray("" ) << QStringLiteral("d41d8cd98f00b204e9800998ecf8427e" ); |
185 | QTest::newRow(dataTag: "md5(a)" ) << QByteArray("a" ) << QStringLiteral("0cc175b9c0f1b6a831c399e269772661" ); |
186 | QTest::newRow(dataTag: "md5(abc)" ) << QByteArray("abc" ) << QStringLiteral("900150983cd24fb0d6963f7d28e17f72" ); |
187 | QTest::newRow(dataTag: "md5(messageDigest)" ) << QByteArray("message digest" ) |
188 | << QStringLiteral("f96b697d7cb7938d525a2f31aaf161d0" ); |
189 | QTest::newRow(dataTag: "md5([a-z])" ) << QByteArray("abcdefghijklmnopqrstuvwxyz" ) |
190 | << QStringLiteral("c3fcd3d76192e4007dfb496cca67e13b" ); |
191 | QTest::newRow(dataTag: "md5([A-z,0-9])" ) << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) |
192 | << QStringLiteral("d174ab98d277d9f5a5611c2c9f419d9f" ); |
193 | QTest::newRow(dataTag: "md5(nums)" ) |
194 | << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890" ) |
195 | << QStringLiteral("57edf4a22be3c955ac49da2e2107b67a" ); |
196 | } |
197 | |
198 | void HashUnitTest::md5test() |
199 | { |
200 | bool anyProviderTested = false; |
201 | QFETCH(QByteArray, input); |
202 | QFETCH(QString, expectedHash); |
203 | |
204 | foreach (QString provider, providersToTest) { |
205 | if (QCA::isSupported(features: "md5" , provider)) { |
206 | anyProviderTested = true; |
207 | |
208 | QCA::Hash hash = QCA::Hash(QStringLiteral("md5" ), provider); |
209 | QCA::Hash copy = hash; |
210 | hash.context(); // detach |
211 | |
212 | QCOMPARE(hash.hashToString(input), expectedHash); |
213 | QCOMPARE(copy.hashToString(input), expectedHash); |
214 | } |
215 | } |
216 | if (!anyProviderTested) |
217 | qWarning() << "NONE of the providers supports MD2:" << providersToTest; |
218 | } |
219 | |
220 | void HashUnitTest::md5filetest() |
221 | { |
222 | foreach (QString provider, providersToTest) { |
223 | if (!QCA::isSupported(features: "md5" , provider)) { |
224 | QFile f1(QStringLiteral(TEST_DATA_DIR "/data/empty" )); |
225 | QVERIFY(f1.open(QIODevice::ReadOnly)); |
226 | { |
227 | QCA::Hash hashObj(QStringLiteral("md5" ), provider); |
228 | hashObj.update(file: &f1); |
229 | QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())), |
230 | QStringLiteral("d41d8cd98f00b204e9800998ecf8427e" )); |
231 | } |
232 | |
233 | QFile f2(QStringLiteral(TEST_DATA_DIR "/data/twobytes" )); |
234 | QVERIFY(f2.open(QIODevice::ReadOnly)); |
235 | { |
236 | QCA::Hash hashObj(QStringLiteral("md5" ), provider); |
237 | hashObj.update(file: &f2); |
238 | QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())), |
239 | QStringLiteral("5fc9808ed18e442ab4164c59f151e757" )); |
240 | } |
241 | |
242 | QFile f3(QStringLiteral(TEST_DATA_DIR "/data/twohundredbytes" )); |
243 | QVERIFY(f3.open(QIODevice::ReadOnly)); |
244 | { |
245 | QCA::Hash hashObj(QStringLiteral("md5" ), provider); |
246 | hashObj.update(file: &f3); |
247 | QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())), |
248 | QStringLiteral("b91c1f114d942520ecdf7e84e580cda3" )); |
249 | } |
250 | } |
251 | } |
252 | } |
253 | |
254 | void HashUnitTest::sha0test_data() |
255 | { |
256 | // These are extracted from OpenOffice.org 1.1.2, in sal/workben/t_digest.c |
257 | // Check FIPS 180-1? |
258 | QTest::addColumn<QByteArray>(name: "input" ); |
259 | QTest::addColumn<QString>(name: "expectedHash" ); |
260 | |
261 | QTest::newRow(dataTag: "sha0(abc)" ) << QByteArray("abc" ) << QStringLiteral("0164b8a914cd2a5e74c4f7ff082c4d97f1edf880" ); |
262 | QTest::newRow(dataTag: "sha0(abc)" ) << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) |
263 | << QStringLiteral("d2516ee1acfa5baf33dfc1c471e438449ef134c8" ); |
264 | } |
265 | |
266 | void HashUnitTest::sha0test() |
267 | { |
268 | bool anyProviderTested = false; |
269 | QFETCH(QByteArray, input); |
270 | QFETCH(QString, expectedHash); |
271 | |
272 | foreach (QString provider, providersToTest) { |
273 | if (QCA::isSupported(features: "sha0" , provider)) { |
274 | anyProviderTested = true; |
275 | |
276 | QCA::Hash hash = QCA::Hash(QStringLiteral("sha0" ), provider); |
277 | QCA::Hash copy = hash; |
278 | hash.context(); // detach |
279 | |
280 | QCOMPARE(hash.hashToString(input), expectedHash); |
281 | QCOMPARE(copy.hashToString(input), expectedHash); |
282 | } |
283 | } |
284 | if (!anyProviderTested) |
285 | qWarning() << "NONE of the providers supports SHA0:" << providersToTest; |
286 | } |
287 | |
288 | void HashUnitTest::sha0longtest() |
289 | { |
290 | QByteArray fillerString; |
291 | fillerString.fill(c: 'a', size: 1000); |
292 | |
293 | // This test extracted from OpenOffice.org 1.1.2, in sal/workben/t_digest.c |
294 | |
295 | foreach (QString provider, providersToTest) { |
296 | if (QCA::isSupported(features: "sha0" , provider)) { |
297 | QCA::Hash shaHash(QStringLiteral("sha0" ), provider); |
298 | for (int i = 0; i < 1000; i++) |
299 | shaHash.update(a: fillerString); |
300 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
301 | QStringLiteral("3232affa48628a26653b5aaa44541fd90d690603" )); |
302 | |
303 | shaHash.clear(); |
304 | for (int i = 0; i < 1000; i++) |
305 | shaHash.update(a: fillerString); |
306 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
307 | QStringLiteral("3232affa48628a26653b5aaa44541fd90d690603" )); |
308 | } |
309 | } |
310 | } |
311 | |
312 | void HashUnitTest::sha1test_data() |
313 | { |
314 | // These are as specified in FIPS 180-2. Matches RFC3174 |
315 | // Some additions from Australian Standard (AS) 2805.13.3-2000 |
316 | QTest::addColumn<QByteArray>(name: "input" ); |
317 | QTest::addColumn<QString>(name: "expectedHash" ); |
318 | |
319 | // FIPS 180-2, Appendix A.1 |
320 | QTest::newRow(dataTag: "sha1(abc)" ) << QByteArray("abc" ) << QStringLiteral("a9993e364706816aba3e25717850c26c9cd0d89d" ); |
321 | |
322 | // FIPS 180-2, Appendix A.2 |
323 | QTest::newRow(dataTag: "sha1(a-q)" ) << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) |
324 | << QStringLiteral("84983e441c3bd26ebaae4aa1f95129e5e54670f1" ); |
325 | |
326 | // AS 2805.13.3-200 Appendix A |
327 | // also has some duplicates from FIPS 180-2 |
328 | QTest::newRow(dataTag: "sha1()" ) << QByteArray("" ) << QStringLiteral("da39a3ee5e6b4b0d3255bfef95601890afd80709" ); |
329 | QTest::newRow(dataTag: "sha1(a)" ) << QByteArray("a" ) << QStringLiteral("86f7e437faa5a7fce15d1ddcb9eaeaea377667b8" ); |
330 | QTest::newRow(dataTag: "sha1(a-z)" ) << QByteArray("abcdefghijklmnopqrstuvwxyz" ) |
331 | << QStringLiteral("32d10c7b8cf96570ca04ce37f2a19d84240d3a89" ); |
332 | } |
333 | |
334 | void HashUnitTest::sha1test() |
335 | { |
336 | bool anyProviderTested = false; |
337 | QFETCH(QByteArray, input); |
338 | QFETCH(QString, expectedHash); |
339 | |
340 | foreach (QString provider, providersToTest) { |
341 | if (QCA::isSupported(features: "sha1" , provider)) { |
342 | anyProviderTested = true; |
343 | |
344 | QCA::Hash hash = QCA::Hash(QStringLiteral("sha1" ), provider); |
345 | QCA::Hash copy = hash; |
346 | hash.context(); // detach |
347 | |
348 | QCOMPARE(hash.hashToString(input), expectedHash); |
349 | QCOMPARE(copy.hashToString(input), expectedHash); |
350 | } |
351 | } |
352 | if (!anyProviderTested) |
353 | qWarning() << "NONE of the providers supports SHA1:" << providersToTest; |
354 | } |
355 | |
356 | void HashUnitTest::sha1longtest() |
357 | { |
358 | foreach (QString provider, providersToTest) { |
359 | if (QCA::isSupported(features: "sha1" , provider)) { |
360 | // QTime t; |
361 | // t.start(); |
362 | QByteArray fillerString; |
363 | fillerString.fill(c: 'a', size: 1000); |
364 | |
365 | // This test extracted from OpenOffice.org 1.1.2, in sal/workben/t_digest.c |
366 | // It basically reflects FIPS 180-2, Appendix A.3 |
367 | // Also as per AS 2805.13.3-2000 Appendix A |
368 | QCA::Hash shaHash(QStringLiteral("sha1" ), provider); |
369 | for (int i = 0; i < 1000; i++) |
370 | shaHash.update(a: fillerString); |
371 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
372 | QStringLiteral("34aa973cd4c4daa4f61eeb2bdbad27316534016f" )); |
373 | |
374 | QFile f1(QStringLiteral(TEST_DATA_DIR "/data/empty" )); |
375 | QVERIFY(f1.open(QIODevice::ReadOnly)); |
376 | { |
377 | QCA::Hash hashObj(QStringLiteral("sha1" ), provider); |
378 | hashObj.update(file: &f1); |
379 | QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())), |
380 | QStringLiteral("da39a3ee5e6b4b0d3255bfef95601890afd80709" )); |
381 | } |
382 | |
383 | QFile f2(QStringLiteral(TEST_DATA_DIR "/data/twobytes" )); |
384 | QVERIFY(f2.open(QIODevice::ReadOnly)); |
385 | { |
386 | QCA::Hash hashObj(QStringLiteral("sha1" ), provider); |
387 | hashObj.update(file: &f2); |
388 | QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())), |
389 | QStringLiteral("efbd6de3c51ca16094391e837bf52f7452593e5c" )); |
390 | } |
391 | |
392 | QFile f3(QStringLiteral(TEST_DATA_DIR "/data/twohundredbytes" )); |
393 | QVERIFY(f3.open(QIODevice::ReadOnly)); |
394 | { |
395 | QCA::Hash hashObj(QStringLiteral("sha1" ), provider); |
396 | hashObj.update(file: &f3); |
397 | QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())), |
398 | QStringLiteral("d636519dfb18d913acbe69fc3ee5a4c7ac870297" )); |
399 | } |
400 | } |
401 | } |
402 | } |
403 | |
404 | void HashUnitTest::sha224test_data() |
405 | { |
406 | QTest::addColumn<QByteArray>(name: "input" ); |
407 | QTest::addColumn<QString>(name: "expectedHash" ); |
408 | |
409 | // These are as specified in FIPS 180-2, change notice 1 |
410 | |
411 | // FIPS 180-2, Appendix B.1 |
412 | QTest::newRow(dataTag: "sha224(abc)" ) << QByteArray("abc" ) |
413 | << QStringLiteral("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" ); |
414 | |
415 | // FIPS 180-2, Appendix B.2 |
416 | QTest::newRow(dataTag: "sha224(aq)" ) << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) |
417 | << QStringLiteral("75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" ); |
418 | } |
419 | |
420 | void HashUnitTest::sha224test() |
421 | { |
422 | bool anyProviderTested = false; |
423 | QFETCH(QByteArray, input); |
424 | QFETCH(QString, expectedHash); |
425 | |
426 | foreach (QString provider, providersToTest) { |
427 | if (QCA::isSupported(features: "sha224" , provider)) { |
428 | anyProviderTested = true; |
429 | |
430 | QCA::Hash hash = QCA::Hash(QStringLiteral("sha224" ), provider); |
431 | QCA::Hash copy = hash; |
432 | hash.context(); // detach |
433 | |
434 | QCOMPARE(hash.hashToString(input), expectedHash); |
435 | QCOMPARE(copy.hashToString(input), expectedHash); |
436 | } |
437 | } |
438 | if (!anyProviderTested) |
439 | qWarning() << "NONE of the providers supports SHA224:" << providersToTest; |
440 | } |
441 | |
442 | void HashUnitTest::sha224longtest() |
443 | { |
444 | QByteArray fillerString; |
445 | fillerString.fill(c: 'a', size: 1000); |
446 | |
447 | foreach (QString provider, providersToTest) { |
448 | if (QCA::isSupported(features: "sha224" , provider)) { |
449 | QCA::Hash shaHash(QStringLiteral("sha224" ), provider); |
450 | |
451 | // This basically reflects FIPS 180-2, change notice 1, section 3 |
452 | for (int i = 0; i < 1000; i++) |
453 | shaHash.update(a: fillerString); |
454 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
455 | QStringLiteral("20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67" )); |
456 | |
457 | shaHash.clear(); |
458 | for (int i = 0; i < 1000; i++) |
459 | shaHash.update(a: fillerString); |
460 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
461 | QStringLiteral("20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67" )); |
462 | } |
463 | } |
464 | } |
465 | |
466 | void HashUnitTest::sha256test_data() |
467 | { |
468 | QTest::addColumn<QByteArray>(name: "input" ); |
469 | QTest::addColumn<QString>(name: "expectedHash" ); |
470 | |
471 | // These are as specified in FIPS 180-2 |
472 | |
473 | // FIPS 180-2, Appendix B.1 |
474 | QTest::newRow(dataTag: "sha256(abc)" ) << QByteArray("abc" ) |
475 | << QStringLiteral("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" ); |
476 | |
477 | // FIPS 180-2, Appendix B.2 |
478 | QTest::newRow(dataTag: "sha256(abc)" ) << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) |
479 | << QStringLiteral("248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" ); |
480 | } |
481 | |
482 | void HashUnitTest::sha256test() |
483 | { |
484 | bool anyProviderTested = false; |
485 | QFETCH(QByteArray, input); |
486 | QFETCH(QString, expectedHash); |
487 | |
488 | foreach (QString provider, providersToTest) { |
489 | if (QCA::isSupported(features: "sha256" , provider)) { |
490 | anyProviderTested = true; |
491 | |
492 | QCA::Hash hash = QCA::Hash(QStringLiteral("sha256" ), provider); |
493 | QCA::Hash copy = hash; |
494 | hash.context(); // detach |
495 | |
496 | QCOMPARE(hash.hashToString(input), expectedHash); |
497 | QCOMPARE(copy.hashToString(input), expectedHash); |
498 | } |
499 | } |
500 | if (!anyProviderTested) |
501 | qWarning() << "NONE of the providers supports SHA256:" << providersToTest; |
502 | } |
503 | |
504 | void HashUnitTest::sha256longtest() |
505 | { |
506 | QByteArray fillerString; |
507 | fillerString.fill(c: 'a', size: 1000); |
508 | |
509 | foreach (QString provider, providersToTest) { |
510 | if (QCA::isSupported(features: "sha256" , provider)) { |
511 | QCA::Hash shaHash(QStringLiteral("sha256" ), provider); |
512 | |
513 | // This basically reflects FIPS 180-2, change notice 1, section 3 |
514 | for (int i = 0; i < 1000; i++) |
515 | shaHash.update(a: fillerString); |
516 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
517 | QStringLiteral("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" )); |
518 | |
519 | shaHash.clear(); |
520 | for (int i = 0; i < 1000; i++) |
521 | shaHash.update(a: fillerString); |
522 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
523 | QStringLiteral("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" )); |
524 | } |
525 | } |
526 | } |
527 | |
528 | void HashUnitTest::sha384test_data() |
529 | { |
530 | QTest::addColumn<QByteArray>(name: "input" ); |
531 | QTest::addColumn<QString>(name: "expectedHash" ); |
532 | |
533 | // These are as specified in FIPS 180-2, and from Aaron Gifford's SHA2 tests |
534 | |
535 | // FIPS 180-2, Appendix B.1 |
536 | QTest::newRow(dataTag: "sha384(abc)" ) |
537 | << QByteArray("abc" ) |
538 | << QStringLiteral( |
539 | "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" ); |
540 | |
541 | // FIPS 180-2, Appendix B.2 |
542 | QTest::newRow(dataTag: "sha384(a-u)" ) |
543 | << QByteArray( |
544 | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrs" |
545 | "tnopqrstu" ) |
546 | << QStringLiteral( |
547 | "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039" ); |
548 | |
549 | // Aaron Gifford, vector002.info |
550 | QTest::newRow(dataTag: "sha384(a-q)" ) |
551 | << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) |
552 | << QStringLiteral( |
553 | "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b" ); |
554 | } |
555 | |
556 | void HashUnitTest::sha384test() |
557 | { |
558 | bool anyProviderTested = false; |
559 | QFETCH(QByteArray, input); |
560 | QFETCH(QString, expectedHash); |
561 | |
562 | foreach (QString provider, providersToTest) { |
563 | if (QCA::isSupported(features: "sha384" , provider)) { |
564 | anyProviderTested = true; |
565 | |
566 | QCA::Hash hash = QCA::Hash(QStringLiteral("sha384" ), provider); |
567 | QCA::Hash copy = hash; |
568 | hash.context(); // detach |
569 | |
570 | QCOMPARE(hash.hashToString(input), expectedHash); |
571 | QCOMPARE(copy.hashToString(input), expectedHash); |
572 | } |
573 | } |
574 | if (!anyProviderTested) |
575 | qWarning() << "NONE of the providers supports SHA384:" << providersToTest; |
576 | } |
577 | |
578 | void HashUnitTest::sha384longtest() |
579 | { |
580 | QByteArray fillerString; |
581 | fillerString.fill(c: 'a', size: 1000); |
582 | |
583 | foreach (QString provider, providersToTest) { |
584 | if (QCA::isSupported(features: "sha384" , provider)) { |
585 | // QTime t; |
586 | // t.start(); |
587 | QCA::Hash shaHash(QStringLiteral("sha384" ), provider); |
588 | |
589 | // This basically reflects FIPS 180-2, change notice 1, section 3 |
590 | for (int i = 0; i < 1000; i++) |
591 | shaHash.update(a: fillerString); |
592 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
593 | QStringLiteral("9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae" |
594 | "97ddd87f3d8985" )); |
595 | |
596 | shaHash.clear(); |
597 | for (int i = 0; i < 1000; i++) |
598 | shaHash.update(a: fillerString); |
599 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
600 | QStringLiteral("9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae" |
601 | "97ddd87f3d8985" )); |
602 | // qDebug() << "SHA384: " << provider << " elapsed " << t.elapsed(); |
603 | } |
604 | } |
605 | } |
606 | |
607 | // These are as specified in FIPS 180-2, and from Aaron Gifford's SHA2 tests |
608 | void HashUnitTest::sha512test_data() |
609 | { |
610 | QTest::addColumn<QByteArray>(name: "input" ); |
611 | QTest::addColumn<QString>(name: "expectedHash" ); |
612 | |
613 | // FIPS 180-2, Appendix C.1 |
614 | QTest::newRow(dataTag: "sha512(abc)" ) << QByteArray("abc" ) |
615 | << QStringLiteral( |
616 | "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1" |
617 | "a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" ); |
618 | // FIPS 180-2, Appendix C.2 |
619 | QTest::newRow(dataTag: "sha512(a-u)" ) << QByteArray( |
620 | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmno" |
621 | "pqklmnopqrlmnopqrsmnopqrstnopqrstu" ) |
622 | << QStringLiteral( |
623 | "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7" |
624 | "e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" ); |
625 | |
626 | // Aaron Gifford, vector002.info |
627 | QTest::newRow(dataTag: "sha512(a-q)" ) << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) |
628 | << QStringLiteral( |
629 | "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07" |
630 | "f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445" ); |
631 | } |
632 | |
633 | void HashUnitTest::sha512test() |
634 | { |
635 | bool anyProviderTested = false; |
636 | QFETCH(QByteArray, input); |
637 | QFETCH(QString, expectedHash); |
638 | |
639 | foreach (QString provider, providersToTest) { |
640 | if (QCA::isSupported(features: "sha512" , provider)) { |
641 | anyProviderTested = true; |
642 | |
643 | QCA::Hash hash = QCA::Hash(QStringLiteral("sha512" ), provider); |
644 | QCA::Hash copy = hash; |
645 | hash.context(); // detach |
646 | |
647 | QCOMPARE(hash.hashToString(input), expectedHash); |
648 | QCOMPARE(copy.hashToString(input), expectedHash); |
649 | } |
650 | } |
651 | if (!anyProviderTested) |
652 | qWarning() << "NONE of the providers supports SHA512:" << providersToTest; |
653 | } |
654 | |
655 | void HashUnitTest::sha512longtest() |
656 | { |
657 | QByteArray fillerString; |
658 | fillerString.fill(c: 'a', size: 1000); |
659 | |
660 | foreach (QString provider, providersToTest) { |
661 | if (QCA::isSupported(features: "sha512" , provider)) { |
662 | QCA::Hash shaHash(QStringLiteral("sha512" ), provider); |
663 | |
664 | // This basically reflects FIPS 180-2, change notice 1, section 3 |
665 | for (int i = 0; i < 1000; i++) |
666 | shaHash.update(a: fillerString); |
667 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
668 | QStringLiteral("e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4c" |
669 | "b0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" )); |
670 | |
671 | shaHash.clear(); |
672 | for (int i = 0; i < 1000; i++) |
673 | shaHash.update(a: fillerString); |
674 | QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())), |
675 | QStringLiteral("e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4c" |
676 | "b0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" )); |
677 | } |
678 | } |
679 | } |
680 | |
681 | // These are as specified in http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html |
682 | // ISO/IEC 10118-3 costs a bit of money. |
683 | void HashUnitTest::rmd160test_data() |
684 | { |
685 | QTest::addColumn<QByteArray>(name: "input" ); |
686 | QTest::addColumn<QString>(name: "expectedHash" ); |
687 | |
688 | QTest::newRow(dataTag: "rmd160()" ) << QByteArray("" ) << QStringLiteral("9c1185a5c5e9fc54612808977ee8f548b2258d31" ); |
689 | QTest::newRow(dataTag: "rmd160(a)" ) << QByteArray("a" ) << QStringLiteral("0bdc9d2d256b3ee9daae347be6f4dc835a467ffe" ); |
690 | QTest::newRow(dataTag: "rmd160(abc)" ) << QByteArray("abc" ) << QStringLiteral("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" ); |
691 | QTest::newRow(dataTag: "rmd160(md)" ) << QByteArray("message digest" ) |
692 | << QStringLiteral("5d0689ef49d2fae572b881b123a85ffa21595f36" ); |
693 | QTest::newRow(dataTag: "rmd160(a-z)" ) << QByteArray("abcdefghijklmnopqrstuvwxyz" ) |
694 | << QStringLiteral("f71c27109c692c1b56bbdceb5b9d2865b3708dbc" ); |
695 | QTest::newRow(dataTag: "rmd160(a-q)" ) << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) |
696 | << QStringLiteral("12a053384a9c0c88e405a06c27dcf49ada62eb2b" ); |
697 | QTest::newRow(dataTag: "rmd160(A-9)" ) << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) |
698 | << QStringLiteral("b0e20b6e3116640286ed3a87a5713079b21f5189" ); |
699 | QTest::newRow(dataTag: "rmd160(1-0)" ) |
700 | << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890" ) |
701 | << QStringLiteral("9b752e45573d4b39f4dbd3323cab82bf63326bfb" ); |
702 | } |
703 | |
704 | void HashUnitTest::rmd160test() |
705 | { |
706 | bool anyProviderTested = false; |
707 | QFETCH(QByteArray, input); |
708 | QFETCH(QString, expectedHash); |
709 | |
710 | foreach (QString provider, providersToTest) { |
711 | if (QCA::isSupported(features: "ripemd160" , provider)) { |
712 | anyProviderTested = true; |
713 | |
714 | QCA::Hash hash = QCA::Hash(QStringLiteral("ripemd160" ), provider); |
715 | QCA::Hash copy = hash; |
716 | hash.context(); // detach |
717 | |
718 | QCOMPARE(hash.hashToString(input), expectedHash); |
719 | QCOMPARE(copy.hashToString(input), expectedHash); |
720 | } |
721 | } |
722 | if (!anyProviderTested) |
723 | qWarning() << "NONE of the providers supports RIPEMD160:" << providersToTest; |
724 | } |
725 | |
726 | void HashUnitTest::rmd160longtest() |
727 | { |
728 | QByteArray fillerString; |
729 | fillerString.fill(c: 'a', size: 1000); |
730 | |
731 | foreach (QString provider, providersToTest) { |
732 | if (QCA::isSupported(features: "ripemd160" , provider)) { |
733 | QCA::Hash rmdHash(QStringLiteral("ripemd160" ), provider); |
734 | |
735 | // This is the "million times 'a' test" |
736 | for (int i = 0; i < 1000; i++) |
737 | rmdHash.update(a: fillerString); |
738 | QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())), |
739 | QStringLiteral("52783243c1697bdbe16d37f97f68f08325dc1528" )); |
740 | |
741 | rmdHash.clear(); |
742 | for (int i = 0; i < 1000; i++) |
743 | rmdHash.update(a: fillerString); |
744 | QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())), |
745 | QStringLiteral("52783243c1697bdbe16d37f97f68f08325dc1528" )); |
746 | |
747 | // This is the "8 rounds of 1234567890" test. |
748 | // It also ensure that we can re-use hash objects correctly. |
749 | static char bindata[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30}; |
750 | QByteArray fillerArray(bindata, sizeof(bindata)); // "1234567890" |
751 | rmdHash.clear(); |
752 | for (int i = 0; i < 8; i++) |
753 | rmdHash.update(a: fillerArray); |
754 | QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())), |
755 | QStringLiteral("9b752e45573d4b39f4dbd3323cab82bf63326bfb" )); |
756 | } |
757 | } |
758 | } |
759 | |
760 | // These are from the documentation pack at http://paginas.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html |
761 | void HashUnitTest::whirlpooltest_data() |
762 | { |
763 | QTest::addColumn<QByteArray>(name: "input" ); |
764 | QTest::addColumn<QString>(name: "expectedHash" ); |
765 | |
766 | QTest::newRow(dataTag: "whirlpool()" ) << QByteArray("" ) |
767 | << QStringLiteral( |
768 | "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288f" |
769 | "ebcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3" ); |
770 | QTest::newRow(dataTag: "whirlpool(a)" ) << QByteArray("a" ) |
771 | << QStringLiteral( |
772 | "8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413ae" |
773 | "ff63a42391a39145a591a92200d560195e53b478584fdae231a" ); |
774 | QTest::newRow(dataTag: "whirlpool(abc)" ) << QByteArray("abc" ) |
775 | << QStringLiteral( |
776 | "4e2448a4c6f486bb16b6562c73b4020bf3043e3a731bce721ae1b303d97e6d4c7181eebdb6c" |
777 | "57e277d0e34957114cbd6c797fc9d95d8b582d225292076d4eef5" ); |
778 | QTest::newRow(dataTag: "whirlpool(md)" ) << QByteArray("message digest" ) |
779 | << QStringLiteral( |
780 | "378c84a4126e2dc6e56dcc7458377aac838d00032230f53ce1f5700c0ffb4d3b8421557659ef" |
781 | "55c106b4b52ac5a4aaa692ed920052838f3362e86dbd37a8903e" ); |
782 | QTest::newRow(dataTag: "whirlpool(a-k)" ) << QByteArray("abcdbcdecdefdefgefghfghighijhijk" ) |
783 | << QStringLiteral( |
784 | "2a987ea40f917061f5d6f0a0e4644f488a7a5a52deee656207c562f988e95c6916bdc8031bc" |
785 | "5be1b7b947639fe050b56939baaa0adff9ae6745b7b181c3be3fd" ); |
786 | QTest::newRow(dataTag: "whirlpool(a-z)" ) << QByteArray("abcdefghijklmnopqrstuvwxyz" ) |
787 | << QStringLiteral( |
788 | "f1d754662636ffe92c82ebb9212a484a8d38631ead4238f5442ee13b8054e41b08bf2a9251c" |
789 | "30b6a0b8aae86177ab4a6f68f673e7207865d5d9819a3dba4eb3b" ); |
790 | QTest::newRow(dataTag: "whirlpool(A-9)" ) << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) |
791 | << QStringLiteral( |
792 | "dc37e008cf9ee69bf11f00ed9aba26901dd7c28cdec066cc6af42e40f82f3a1e08eba266291" |
793 | "29d8fb7cb57211b9281a65517cc879d7b962142c65f5a7af01467" ); |
794 | QTest::newRow(dataTag: "whirlpool(1-0)" ) |
795 | << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890" ) |
796 | << QStringLiteral( |
797 | "466ef18babb0154d25b9d38a6414f5c08784372bccb204d6549c4afadb6014294d5bd8df2a6c44e538cd047b2681a51a2c60481" |
798 | "e88c5a20b2c2a80cf3a9a083b" ); |
799 | } |
800 | |
801 | void HashUnitTest::whirlpooltest() |
802 | { |
803 | bool anyProviderTested = false; |
804 | QFETCH(QByteArray, input); |
805 | QFETCH(QString, expectedHash); |
806 | |
807 | foreach (QString provider, providersToTest) { |
808 | if (QCA::isSupported(features: "whirlpool" , provider)) { |
809 | anyProviderTested = true; |
810 | |
811 | QCA::Hash hash = QCA::Hash(QStringLiteral("whirlpool" ), provider); |
812 | QCA::Hash copy = hash; |
813 | hash.context(); // detach |
814 | |
815 | QCOMPARE(hash.hashToString(input), expectedHash); |
816 | QCOMPARE(copy.hashToString(input), expectedHash); |
817 | } |
818 | } |
819 | if (!anyProviderTested) |
820 | qWarning() << "NONE of the providers supports Whirlpool:" << providersToTest; |
821 | } |
822 | |
823 | void HashUnitTest::whirlpoollongtest() |
824 | { |
825 | QByteArray fillerString; |
826 | fillerString.fill(c: 'a', size: 1000); |
827 | |
828 | foreach (QString provider, providersToTest) { |
829 | if (QCA::isSupported(features: "whirlpool" , provider)) { |
830 | QCA::Hash rmdHash(QStringLiteral("whirlpool" ), provider); |
831 | |
832 | // This is the "million times 'a' test" |
833 | for (int i = 0; i < 1000; i++) |
834 | rmdHash.update(a: fillerString); |
835 | QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())), |
836 | QStringLiteral("0c99005beb57eff50a7cf005560ddf5d29057fd86b20bfd62deca0f1ccea4af51fc15490eddc47af32" |
837 | "bb2b66c34ff9ad8c6008ad677f77126953b226e4ed8b01" )); |
838 | |
839 | rmdHash.clear(); |
840 | for (int i = 0; i < 1000; i++) |
841 | rmdHash.update(a: fillerString); |
842 | QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())), |
843 | QStringLiteral("0c99005beb57eff50a7cf005560ddf5d29057fd86b20bfd62deca0f1ccea4af51fc15490eddc47af32" |
844 | "bb2b66c34ff9ad8c6008ad677f77126953b226e4ed8b01" )); |
845 | |
846 | // This is the "8 rounds of 1234567890" test. |
847 | // It also ensure that we can re-use hash objects correctly. |
848 | static char bindata[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30}; |
849 | QByteArray fillerArray(bindata, sizeof(bindata)); // "1234567890" |
850 | rmdHash.clear(); |
851 | for (int i = 0; i < 8; i++) |
852 | rmdHash.update(a: fillerArray); |
853 | QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())), |
854 | QStringLiteral("466ef18babb0154d25b9d38a6414f5c08784372bccb204d6549c4afadb6014294d5bd8df2a6c44e538" |
855 | "cd047b2681a51a2c60481e88c5a20b2c2a80cf3a9a083b" )); |
856 | } |
857 | } |
858 | } |
859 | |
860 | QTEST_MAIN(HashUnitTest) |
861 | |
862 | #include "hashunittest.moc" |
863 | |