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 <QtCrypto> |
27 | #include <QtTest/QtTest> |
28 | |
29 | #ifdef QT_STATICPLUGIN |
30 | #include "import_plugins.h" |
31 | #endif |
32 | |
33 | class MACUnitTest : public QObject |
34 | { |
35 | Q_OBJECT |
36 | |
37 | private Q_SLOTS: |
38 | void initTestCase(); |
39 | void cleanupTestCase(); |
40 | void HMACMD5(); |
41 | void HMACSHA1(); |
42 | void HMACSHA256(); |
43 | void HMACSHA224(); |
44 | void HMACSHA384(); |
45 | void HMACSHA512(); |
46 | void HMACRMD160(); |
47 | |
48 | private: |
49 | QCA::Initializer *m_init; |
50 | }; |
51 | |
52 | void MACUnitTest::initTestCase() |
53 | { |
54 | m_init = new QCA::Initializer; |
55 | } |
56 | |
57 | void MACUnitTest::cleanupTestCase() |
58 | { |
59 | delete m_init; |
60 | } |
61 | |
62 | void MACUnitTest::HMACMD5() |
63 | { |
64 | QStringList providersToTest; |
65 | providersToTest.append(QStringLiteral("qca-ossl" )); |
66 | providersToTest.append(QStringLiteral("qca-gcrypt" )); |
67 | providersToTest.append(QStringLiteral("qca-botan" )); |
68 | providersToTest.append(QStringLiteral("qca-nss" )); |
69 | |
70 | foreach (const QString provider, providersToTest) { |
71 | if (!QCA::isSupported(features: "hmac(md5)" , provider)) |
72 | QWARN((QStringLiteral("HMAC(MD5) not supported for " ) + provider).toLocal8Bit().constData()); |
73 | else { |
74 | QCA::MessageAuthenticationCode md5hmacLenTest(QStringLiteral("hmac(md5)" ), QCA::SymmetricKey(), provider); |
75 | QCOMPARE(md5hmacLenTest.validKeyLength(0), true); |
76 | QCOMPARE(md5hmacLenTest.validKeyLength(1), true); |
77 | QCOMPARE(md5hmacLenTest.validKeyLength(848888), true); |
78 | QCOMPARE(md5hmacLenTest.validKeyLength(-2), false); |
79 | |
80 | QCA::MessageAuthenticationCode copy = md5hmacLenTest; |
81 | copy.context(); // detach |
82 | |
83 | // These tests are from RFC2202, Section 2. |
84 | // The first three are also in the Appendix to RFC2104 |
85 | QCA::MessageAuthenticationCode md5hmac1(QStringLiteral("hmac(md5)" ), QCA::SymmetricKey(), provider); |
86 | QCA::SymmetricKey key1(QCA::SecureArray("Jefe" )); |
87 | md5hmac1.setup(key1); |
88 | QCA::SecureArray data1("what do ya want for nothing?" ); |
89 | md5hmac1.update(array: data1); |
90 | QCOMPARE(QCA::arrayToHex(md5hmac1.final().toByteArray()), |
91 | QStringLiteral("750c783e6ab0b503eaa86e310a5db738" )); |
92 | |
93 | QCA::MessageAuthenticationCode md5hmac2(QStringLiteral("hmac(md5)" ), QCA::SymmetricKey(), provider); |
94 | QCA::SymmetricKey key2(QCA::hexToArray(QStringLiteral("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" ))); |
95 | md5hmac2.setup(key2); |
96 | QCA::SecureArray data2 = QCA::SecureArray("Hi There" ); |
97 | md5hmac2.update(array: data2); |
98 | QCOMPARE(QCA::arrayToHex(md5hmac2.final().toByteArray()), |
99 | QStringLiteral("9294727a3638bb1c13f48ef8158bfc9d" )); |
100 | |
101 | // test reuse |
102 | md5hmac2.clear(); |
103 | QCA::SymmetricKey key3(QCA::hexToArray(QStringLiteral("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ))); |
104 | md5hmac2.setup(key3); |
105 | QCA::SecureArray data3(50); |
106 | for (int i = 0; i < data3.size(); i++) |
107 | data3[i] = (char)0xDD; |
108 | md5hmac2.update(array: data3); |
109 | QCOMPARE(QCA::arrayToHex(md5hmac2.final().toByteArray()), |
110 | QStringLiteral("56be34521d144c88dbb8c733f0e8b3f6" )); |
111 | |
112 | QCA::SymmetricKey key4( |
113 | QCA::hexToArray(QStringLiteral("0102030405060708090a0b0c0d0e0f10111213141516171819" ))); |
114 | QCA::MessageAuthenticationCode md5hmac4(QStringLiteral("hmac(md5)" ), key4, provider); |
115 | QCA::SecureArray data4(50); |
116 | for (int i = 0; i < data4.size(); i++) |
117 | data4[i] = (char)0xcd; |
118 | md5hmac4.update(array: data4); |
119 | QCOMPARE(QCA::arrayToHex(md5hmac4.final().toByteArray()), |
120 | QStringLiteral("697eaf0aca3a3aea3a75164746ffaa79" )); |
121 | |
122 | QCA::MessageAuthenticationCode md5hmac5(QStringLiteral("hmac(md5)" ), QCA::SecureArray()); |
123 | QCA::SymmetricKey key5(QCA::hexToArray(QStringLiteral("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c" ))); |
124 | md5hmac5.setup(key5); |
125 | QCA::SecureArray data5("Test With Truncation" ); |
126 | md5hmac5.update(array: data5); |
127 | QCOMPARE(QCA::arrayToHex(md5hmac5.final().toByteArray()), |
128 | QStringLiteral("56461ef2342edc00f9bab995690efd4c" )); |
129 | |
130 | QCA::MessageAuthenticationCode md5hmac6(QStringLiteral("hmac(md5)" ), QCA::SymmetricKey(), provider); |
131 | QCA::SymmetricKey key6(80); |
132 | for (int i = 0; i < key6.size(); i++) |
133 | key6[i] = (char)0xaa; |
134 | md5hmac6.setup(key6); |
135 | QCA::SecureArray data6("Test Using Larger Than Block-Size Key - Hash Key First" ); |
136 | md5hmac6.update(array: data6); |
137 | QCOMPARE(QCA::arrayToHex(md5hmac6.final().toByteArray()), |
138 | QStringLiteral("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd" )); |
139 | |
140 | md5hmac6.clear(); // reuse the same key |
141 | QCA::SecureArray data7("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" ); |
142 | md5hmac6.update(array: data7); |
143 | QCOMPARE(QCA::arrayToHex(md5hmac6.final().toByteArray()), |
144 | QStringLiteral("6f630fad67cda0ee1fb1f562db3aa53e" )); |
145 | } |
146 | } |
147 | } |
148 | |
149 | void MACUnitTest::HMACSHA256() |
150 | { |
151 | QStringList providersToTest; |
152 | providersToTest.append(QStringLiteral("qca-ossl" )); |
153 | providersToTest.append(QStringLiteral("qca-gcrypt" )); |
154 | providersToTest.append(QStringLiteral("qca-botan" )); |
155 | providersToTest.append(QStringLiteral("qca-nss" )); |
156 | |
157 | foreach (const QString provider, providersToTest) { |
158 | if (!QCA::isSupported(features: "hmac(sha256)" , provider)) |
159 | QWARN((QStringLiteral("HMAC(SHA256) not supported for " ) + provider).toLocal8Bit().constData()); |
160 | else { |
161 | QCA::MessageAuthenticationCode hmacLenTest(QStringLiteral("hmac(sha256)" ), QCA::SymmetricKey(), provider); |
162 | QCOMPARE(hmacLenTest.validKeyLength(0), true); |
163 | QCOMPARE(hmacLenTest.validKeyLength(1), true); |
164 | QCOMPARE(hmacLenTest.validKeyLength(848888), true); |
165 | QCOMPARE(hmacLenTest.validKeyLength(-2), false); |
166 | |
167 | QCA::MessageAuthenticationCode copy = hmacLenTest; |
168 | copy.context(); // detach |
169 | |
170 | QCA::MessageAuthenticationCode hmac1(QStringLiteral("hmac(sha256)" ), QCA::SymmetricKey(), provider); |
171 | QCA::SymmetricKey key1(QCA::SecureArray("Jefe" )); |
172 | hmac1.setup(key1); |
173 | QCA::SecureArray data1("what do ya want for nothing?" ); |
174 | hmac1.update(array: data1); |
175 | QCOMPARE(QCA::arrayToHex(hmac1.final().toByteArray()), |
176 | QStringLiteral("5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843" )); |
177 | |
178 | QCA::MessageAuthenticationCode hmac2(QStringLiteral("hmac(sha256)" ), QCA::SymmetricKey(), provider); |
179 | QCA::SymmetricKey key2(QCA::hexToArray(QStringLiteral("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" ))); |
180 | hmac2.setup(key2); |
181 | QCA::SecureArray data2 = QCA::SecureArray("Hi There" ); |
182 | hmac2.update(array: data2); |
183 | QCOMPARE(QCA::arrayToHex(hmac2.final().toByteArray()), |
184 | QStringLiteral("b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7" )); |
185 | |
186 | // test reuse |
187 | hmac2.clear(); |
188 | QCA::SymmetricKey key3(QCA::hexToArray(QStringLiteral("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))); |
189 | hmac2.setup(key3); |
190 | QCA::SecureArray data3(50); |
191 | for (int i = 0; i < data3.size(); i++) |
192 | data3[i] = (char)0xDD; |
193 | hmac2.update(array: data3); |
194 | QCOMPARE(QCA::arrayToHex(hmac2.final().toByteArray()), |
195 | QStringLiteral("773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe" )); |
196 | |
197 | QCA::SymmetricKey key4( |
198 | QCA::hexToArray(QStringLiteral("0102030405060708090a0b0c0d0e0f10111213141516171819" ))); |
199 | QCA::MessageAuthenticationCode hmac4(QStringLiteral("hmac(sha256)" ), key4, provider); |
200 | QCA::SecureArray data4(50); |
201 | for (int i = 0; i < data4.size(); i++) |
202 | data4[i] = (char)0xcd; |
203 | hmac4.update(array: data4); |
204 | QCOMPARE(QCA::arrayToHex(hmac4.final().toByteArray()), |
205 | QStringLiteral("82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b" )); |
206 | |
207 | QCA::MessageAuthenticationCode hmac5(QStringLiteral("hmac(sha256)" ), QCA::SymmetricKey(), provider); |
208 | QCA::SymmetricKey key5(QCA::hexToArray(QStringLiteral("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c" ))); |
209 | hmac5.setup(key5); |
210 | QCA::SecureArray data5("Test With Truncation" ); |
211 | hmac5.update(array: data5); |
212 | QString resultWithTrunc = QCA::arrayToHex(array: hmac5.final().toByteArray()); |
213 | resultWithTrunc.resize(size: 32); |
214 | QCOMPARE(resultWithTrunc, QStringLiteral("a3b6167473100ee06e0c796c2955552b" )); |
215 | |
216 | QCA::MessageAuthenticationCode hmac6(QStringLiteral("hmac(sha256)" ), QCA::SymmetricKey(), provider); |
217 | QCA::SymmetricKey key6(131); |
218 | for (int i = 0; i < key6.size(); i++) |
219 | key6[i] = (char)0xaa; |
220 | hmac6.setup(key6); |
221 | QCA::SecureArray data6("Test Using Larger Than Block-Size Key - Hash Key First" ); |
222 | hmac6.update(array: data6); |
223 | QCOMPARE(QCA::arrayToHex(hmac6.final().toByteArray()), |
224 | QStringLiteral("60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54" )); |
225 | |
226 | hmac6.clear(); // reuse the same key |
227 | QCA::SecureArray data7( |
228 | "This is a test using a larger than block-size key and a larger than block-size data. The key needs to " |
229 | "be hashed before being used by the HMAC algorithm." ); |
230 | hmac6.update(array: data7); |
231 | QCOMPARE(QCA::arrayToHex(hmac6.final().toByteArray()), |
232 | QStringLiteral("9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2" )); |
233 | } |
234 | } |
235 | } |
236 | |
237 | void MACUnitTest::HMACSHA224() |
238 | { |
239 | QStringList providersToTest; |
240 | providersToTest.append(QStringLiteral("qca-ossl" )); |
241 | providersToTest.append(QStringLiteral("qca-gcrypt" )); |
242 | providersToTest.append(QStringLiteral("qca-botan" )); |
243 | |
244 | foreach (const QString provider, providersToTest) { |
245 | if (!QCA::isSupported(features: "hmac(sha224)" , provider)) |
246 | QWARN((QStringLiteral("HMAC(SHA224) not supported for " ) + provider).toLocal8Bit().constData()); |
247 | else { |
248 | QCA::MessageAuthenticationCode hmacLenTest(QStringLiteral("hmac(sha224)" ), QCA::SymmetricKey(), provider); |
249 | QCOMPARE(hmacLenTest.validKeyLength(0), true); |
250 | QCOMPARE(hmacLenTest.validKeyLength(1), true); |
251 | QCOMPARE(hmacLenTest.validKeyLength(848888), true); |
252 | QCOMPARE(hmacLenTest.validKeyLength(-2), false); |
253 | |
254 | QCA::MessageAuthenticationCode copy = hmacLenTest; |
255 | copy.context(); // detach |
256 | |
257 | QCA::MessageAuthenticationCode hmac1(QStringLiteral("hmac(sha224)" ), QCA::SymmetricKey(), provider); |
258 | QCA::SymmetricKey key1(QCA::SecureArray("Jefe" )); |
259 | hmac1.setup(key1); |
260 | QCA::SecureArray data1("what do ya want for nothing?" ); |
261 | hmac1.update(array: data1); |
262 | QCOMPARE(QCA::arrayToHex(hmac1.final().toByteArray()), |
263 | QStringLiteral("a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44" )); |
264 | |
265 | QCA::MessageAuthenticationCode hmac2(QStringLiteral("hmac(sha224)" ), QCA::SymmetricKey(), provider); |
266 | QCA::SymmetricKey key2(QCA::hexToArray(QStringLiteral("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" ))); |
267 | hmac2.setup(key2); |
268 | QCA::SecureArray data2 = QCA::SecureArray("Hi There" ); |
269 | hmac2.update(array: data2); |
270 | QCOMPARE(QCA::arrayToHex(hmac2.final().toByteArray()), |
271 | QStringLiteral("896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22" )); |
272 | |
273 | // test reuse |
274 | hmac2.clear(); |
275 | QCA::SymmetricKey key3(QCA::hexToArray(QStringLiteral("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))); |
276 | hmac2.setup(key3); |
277 | QCA::SecureArray data3(50); |
278 | for (int i = 0; i < data3.size(); i++) |
279 | data3[i] = (char)0xDD; |
280 | hmac2.update(array: data3); |
281 | QCOMPARE(QCA::arrayToHex(hmac2.final().toByteArray()), |
282 | QStringLiteral("7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea" )); |
283 | |
284 | QCA::SymmetricKey key4( |
285 | QCA::hexToArray(QStringLiteral("0102030405060708090a0b0c0d0e0f10111213141516171819" ))); |
286 | QCA::MessageAuthenticationCode hmac4(QStringLiteral("hmac(sha224)" ), key4, provider); |
287 | QCA::SecureArray data4(50); |
288 | for (int i = 0; i < data4.size(); i++) |
289 | data4[i] = (char)0xcd; |
290 | hmac4.update(array: data4); |
291 | QCOMPARE(QCA::arrayToHex(hmac4.final().toByteArray()), |
292 | QStringLiteral("6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a" )); |
293 | |
294 | QCA::MessageAuthenticationCode hmac5(QStringLiteral("hmac(sha224)" ), QCA::SymmetricKey(), provider); |
295 | QCA::SymmetricKey key5(QCA::hexToArray(QStringLiteral("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c" ))); |
296 | hmac5.setup(key5); |
297 | QCA::SecureArray data5("Test With Truncation" ); |
298 | hmac5.update(array: data5); |
299 | QString resultWithTrunc = QCA::arrayToHex(array: hmac5.final().toByteArray()); |
300 | resultWithTrunc.resize(size: 32); |
301 | QCOMPARE(resultWithTrunc, QStringLiteral("0e2aea68a90c8d37c988bcdb9fca6fa8" )); |
302 | |
303 | QCA::MessageAuthenticationCode hmac6(QStringLiteral("hmac(sha224)" ), QCA::SymmetricKey(), provider); |
304 | QCA::SymmetricKey key6(131); |
305 | for (int i = 0; i < key6.size(); i++) |
306 | key6[i] = (char)0xaa; |
307 | hmac6.setup(key6); |
308 | QCA::SecureArray data6("Test Using Larger Than Block-Size Key - Hash Key First" ); |
309 | hmac6.update(array: data6); |
310 | QCOMPARE(QCA::arrayToHex(hmac6.final().toByteArray()), |
311 | QStringLiteral("95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e" )); |
312 | |
313 | hmac6.clear(); // reuse the same key |
314 | QCA::SecureArray data7( |
315 | "This is a test using a larger than block-size key and a larger than block-size data. The key needs to " |
316 | "be hashed before being used by the HMAC algorithm." ); |
317 | hmac6.update(array: data7); |
318 | QCOMPARE(QCA::arrayToHex(hmac6.final().toByteArray()), |
319 | QStringLiteral("3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1" )); |
320 | } |
321 | } |
322 | } |
323 | |
324 | void MACUnitTest::HMACSHA384() |
325 | { |
326 | QStringList providersToTest; |
327 | providersToTest.append(QStringLiteral("qca-ossl" )); |
328 | providersToTest.append(QStringLiteral("qca-gcrypt" )); |
329 | providersToTest.append(QStringLiteral("qca-botan" )); |
330 | providersToTest.append(QStringLiteral("qca-nss" )); |
331 | |
332 | foreach (const QString provider, providersToTest) { |
333 | if (!QCA::isSupported(features: "hmac(sha384)" , provider)) |
334 | QWARN((QStringLiteral("HMAC(SHA384) not supported for " ) + provider).toLocal8Bit().constData()); |
335 | else { |
336 | QCA::MessageAuthenticationCode hmacLenTest(QStringLiteral("hmac(sha384)" ), QCA::SymmetricKey(), provider); |
337 | QCOMPARE(hmacLenTest.validKeyLength(0), true); |
338 | QCOMPARE(hmacLenTest.validKeyLength(1), true); |
339 | QCOMPARE(hmacLenTest.validKeyLength(848888), true); |
340 | QCOMPARE(hmacLenTest.validKeyLength(-2), false); |
341 | |
342 | QCA::MessageAuthenticationCode copy = hmacLenTest; |
343 | copy.context(); // detach |
344 | |
345 | QCA::MessageAuthenticationCode hmac1(QStringLiteral("hmac(sha384)" ), QCA::SymmetricKey(), provider); |
346 | QCA::SymmetricKey key1(QCA::SecureArray("Jefe" )); |
347 | hmac1.setup(key1); |
348 | QCA::SecureArray data1("what do ya want for nothing?" ); |
349 | hmac1.update(array: data1); |
350 | QCOMPARE(QCA::arrayToHex(hmac1.final().toByteArray()), |
351 | QStringLiteral("af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b" |
352 | "3239ecfab21649" )); |
353 | |
354 | QCA::MessageAuthenticationCode hmac2(QStringLiteral("hmac(sha384)" ), QCA::SymmetricKey(), provider); |
355 | QCA::SymmetricKey key2(QCA::hexToArray(QStringLiteral("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" ))); |
356 | hmac2.setup(key2); |
357 | QCA::SecureArray data2 = QCA::SecureArray("Hi There" ); |
358 | hmac2.update(array: data2); |
359 | QCOMPARE(QCA::arrayToHex(hmac2.final().toByteArray()), |
360 | QStringLiteral("afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4a" |
361 | "f152e8b2fa9cb6" )); |
362 | |
363 | // test reuse |
364 | hmac2.clear(); |
365 | QCA::SymmetricKey key3(QCA::hexToArray(QStringLiteral("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))); |
366 | hmac2.setup(key3); |
367 | QCA::SecureArray data3(50); |
368 | for (int i = 0; i < data3.size(); i++) |
369 | data3[i] = (char)0xDD; |
370 | hmac2.update(array: data3); |
371 | QCOMPARE(QCA::arrayToHex(hmac2.final().toByteArray()), |
372 | QStringLiteral("88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e" |
373 | "3ab6e101a34f27" )); |
374 | |
375 | QCA::SymmetricKey key4( |
376 | QCA::hexToArray(QStringLiteral("0102030405060708090a0b0c0d0e0f10111213141516171819" ))); |
377 | QCA::MessageAuthenticationCode hmac4(QStringLiteral("hmac(sha384)" ), key4, provider); |
378 | QCA::SecureArray data4(50); |
379 | for (int i = 0; i < data4.size(); i++) |
380 | data4[i] = (char)0xcd; |
381 | hmac4.update(array: data4); |
382 | QCOMPARE(QCA::arrayToHex(hmac4.final().toByteArray()), |
383 | QStringLiteral("3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679cc" |
384 | "f8a386c674cffb" )); |
385 | |
386 | QCA::MessageAuthenticationCode hmac5(QStringLiteral("hmac(sha384)" ), QCA::SecureArray(), provider); |
387 | QCA::SymmetricKey key5(QCA::hexToArray(QStringLiteral("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c" ))); |
388 | hmac5.setup(key5); |
389 | QCA::SecureArray data5("Test With Truncation" ); |
390 | hmac5.update(array: data5); |
391 | QString resultWithTrunc = QCA::arrayToHex(array: hmac5.final().toByteArray()); |
392 | resultWithTrunc.resize(size: 32); |
393 | QCOMPARE(resultWithTrunc, QStringLiteral("3abf34c3503b2a23a46efc619baef897" )); |
394 | |
395 | QCA::MessageAuthenticationCode hmac6(QStringLiteral("hmac(sha384)" ), QCA::SymmetricKey(), provider); |
396 | QCA::SymmetricKey key6(131); |
397 | for (int i = 0; i < key6.size(); i++) |
398 | key6[i] = (char)0xaa; |
399 | hmac6.setup(key6); |
400 | QCA::SecureArray data6("Test Using Larger Than Block-Size Key - Hash Key First" ); |
401 | hmac6.update(array: data6); |
402 | QCOMPARE(QCA::arrayToHex(hmac6.final().toByteArray()), |
403 | QStringLiteral("4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296" |
404 | "248df163f44952" )); |
405 | |
406 | hmac6.clear(); // reuse the same key |
407 | QCA::SecureArray data7( |
408 | "This is a test using a larger than block-size key and a larger than block-size data. The key needs to " |
409 | "be hashed before being used by the HMAC algorithm." ); |
410 | hmac6.update(array: data7); |
411 | QCOMPARE(QCA::arrayToHex(hmac6.final().toByteArray()), |
412 | QStringLiteral("6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d38" |
413 | "60e6110c46523e" )); |
414 | } |
415 | } |
416 | } |
417 | |
418 | void MACUnitTest::HMACSHA512() |
419 | { |
420 | QStringList providersToTest; |
421 | providersToTest.append(QStringLiteral("qca-ossl" )); |
422 | providersToTest.append(QStringLiteral("qca-gcrypt" )); |
423 | providersToTest.append(QStringLiteral("qca-botan" )); |
424 | providersToTest.append(QStringLiteral("qca-nss" )); |
425 | |
426 | foreach (const QString provider, providersToTest) { |
427 | if (!QCA::isSupported(features: "hmac(sha512)" , provider)) |
428 | QWARN((QStringLiteral("HMAC(SHA512) not supported for " ) + provider).toLocal8Bit().constData()); |
429 | else { |
430 | QCA::MessageAuthenticationCode hmacLenTest(QStringLiteral("hmac(sha512)" ), QCA::SymmetricKey(), provider); |
431 | QCOMPARE(hmacLenTest.validKeyLength(0), true); |
432 | QCOMPARE(hmacLenTest.validKeyLength(1), true); |
433 | QCOMPARE(hmacLenTest.validKeyLength(848888), true); |
434 | QCOMPARE(hmacLenTest.validKeyLength(-2), false); |
435 | |
436 | QCA::MessageAuthenticationCode copy = hmacLenTest; |
437 | copy.context(); // detach |
438 | |
439 | QCA::MessageAuthenticationCode hmac1(QStringLiteral("hmac(sha512)" ), QCA::SymmetricKey(), provider); |
440 | QCA::SymmetricKey key1(QCA::SecureArray("Jefe" )); |
441 | hmac1.setup(key1); |
442 | QCA::SecureArray data1("what do ya want for nothing?" ); |
443 | hmac1.update(array: data1); |
444 | QCOMPARE(QCA::arrayToHex(hmac1.final().toByteArray()), |
445 | QStringLiteral("164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d" |
446 | "034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737" )); |
447 | |
448 | QCA::MessageAuthenticationCode hmac2(QStringLiteral("hmac(sha512)" ), QCA::SymmetricKey(), provider); |
449 | QCA::SymmetricKey key2(QCA::hexToArray(QStringLiteral("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" ))); |
450 | hmac2.setup(key2); |
451 | QCA::SecureArray data2 = QCA::SecureArray("Hi There" ); |
452 | hmac2.update(array: data2); |
453 | QCOMPARE(QCA::arrayToHex(hmac2.final().toByteArray()), |
454 | QStringLiteral("87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a70203" |
455 | "8b274eaea3f4e4be9d914eeb61f1702e696c203a126854" )); |
456 | |
457 | // test reuse |
458 | hmac2.clear(); |
459 | QCA::SymmetricKey key3(QCA::hexToArray(QStringLiteral("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))); |
460 | hmac2.setup(key3); |
461 | QCA::SecureArray data3(50); |
462 | for (int i = 0; i < data3.size(); i++) |
463 | data3[i] = (char)0xDD; |
464 | hmac2.update(array: data3); |
465 | QCOMPARE(QCA::arrayToHex(hmac2.final().toByteArray()), |
466 | QStringLiteral("fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806" |
467 | "b485a47e67c807b946a337bee8942674278859e13292fb" )); |
468 | |
469 | QCA::SymmetricKey key4( |
470 | QCA::hexToArray(QStringLiteral("0102030405060708090a0b0c0d0e0f10111213141516171819" ))); |
471 | QCA::MessageAuthenticationCode hmac4(QStringLiteral("hmac(sha512)" ), key4, provider); |
472 | QCA::SecureArray data4(50); |
473 | for (int i = 0; i < data4.size(); i++) |
474 | data4[i] = (char)0xcd; |
475 | hmac4.update(array: data4); |
476 | QCOMPARE(QCA::arrayToHex(hmac4.final().toByteArray()), |
477 | QStringLiteral("b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d6" |
478 | "79275cc5788063a5f19741120c4f2de2adebeb10a298dd" )); |
479 | |
480 | QCA::MessageAuthenticationCode hmac5(QStringLiteral("hmac(sha512)" ), QCA::SecureArray(), provider); |
481 | QCA::SymmetricKey key5(QCA::hexToArray(QStringLiteral("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c" ))); |
482 | hmac5.setup(key5); |
483 | QCA::SecureArray data5("Test With Truncation" ); |
484 | hmac5.update(array: data5); |
485 | QString resultWithTrunc = QCA::arrayToHex(array: hmac5.final().toByteArray()); |
486 | resultWithTrunc.resize(size: 32); |
487 | QCOMPARE(resultWithTrunc, QStringLiteral("415fad6271580a531d4179bc891d87a6" )); |
488 | |
489 | QCA::MessageAuthenticationCode hmac6(QStringLiteral("hmac(sha512)" ), QCA::SymmetricKey(), provider); |
490 | QCA::SymmetricKey key6(131); |
491 | for (int i = 0; i < key6.size(); i++) |
492 | key6[i] = (char)0xaa; |
493 | hmac6.setup(key6); |
494 | QCA::SecureArray data6("Test Using Larger Than Block-Size Key - Hash Key First" ); |
495 | hmac6.update(array: data6); |
496 | QCOMPARE(QCA::arrayToHex(hmac6.final().toByteArray()), |
497 | QStringLiteral("80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd" |
498 | "0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598" )); |
499 | |
500 | hmac6.clear(); // reuse the same key |
501 | QCA::SecureArray data7( |
502 | "This is a test using a larger than block-size key and a larger than block-size data. The key needs to " |
503 | "be hashed before being used by the HMAC algorithm." ); |
504 | hmac6.update(array: data7); |
505 | QCOMPARE(QCA::arrayToHex(hmac6.final().toByteArray()), |
506 | QStringLiteral("e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d" |
507 | "5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58" )); |
508 | } |
509 | } |
510 | } |
511 | |
512 | void MACUnitTest::HMACSHA1() |
513 | { |
514 | QStringList providersToTest; |
515 | providersToTest.append(QStringLiteral("qca-ossl" )); |
516 | providersToTest.append(QStringLiteral("qca-gcrypt" )); |
517 | providersToTest.append(QStringLiteral("qca-botan" )); |
518 | providersToTest.append(QStringLiteral("qca-nss" )); |
519 | |
520 | foreach (const QString provider, providersToTest) { |
521 | if (!QCA::isSupported(features: "hmac(sha1)" , provider)) |
522 | QWARN((QStringLiteral("HMAC(SHA1) not supported for " ) + provider).toLocal8Bit().constData()); |
523 | else { |
524 | QCA::MessageAuthenticationCode sha1hmacLenTest(QStringLiteral("hmac(sha1)" ), QCA::SymmetricKey(), provider); |
525 | QCOMPARE(sha1hmacLenTest.validKeyLength(0), true); |
526 | QCOMPARE(sha1hmacLenTest.validKeyLength(1), true); |
527 | QCOMPARE(sha1hmacLenTest.validKeyLength(848888), true); |
528 | QCOMPARE(sha1hmacLenTest.validKeyLength(-2), false); |
529 | |
530 | QCA::MessageAuthenticationCode copy = sha1hmacLenTest; |
531 | copy.context(); // detach |
532 | |
533 | // These tests are from RFC2202, Section 3. |
534 | QCA::MessageAuthenticationCode test1(QStringLiteral("hmac(sha1)" ), QCA::SecureArray()); |
535 | QCA::SymmetricKey key1(QCA::hexToArray(QStringLiteral("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" ))); |
536 | test1.setup(key1); |
537 | QCA::SecureArray data1("Hi There" ); |
538 | test1.update(array: data1); |
539 | QCOMPARE(QCA::arrayToHex(test1.final().toByteArray()), |
540 | QStringLiteral("b617318655057264e28bc0b6fb378c8ef146be00" )); |
541 | |
542 | QCA::MessageAuthenticationCode test2(QStringLiteral("hmac(sha1)" ), QCA::SymmetricKey(), provider); |
543 | QCA::SymmetricKey key2(QCA::SecureArray("Jefe" )); |
544 | test2.setup(key2); |
545 | QCA::SecureArray data2("what do ya want for nothing?" ); |
546 | test2.update(array: data2); |
547 | QCOMPARE(QCA::arrayToHex(test2.final().toByteArray()), |
548 | QStringLiteral("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79" )); |
549 | |
550 | QCA::MessageAuthenticationCode test3(QStringLiteral("hmac(sha1)" ), QCA::SymmetricKey(), provider); |
551 | QCA::SymmetricKey key3(QCA::hexToArray(QStringLiteral("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))); |
552 | test3.setup(key3); |
553 | QCA::SecureArray data3(50); |
554 | for (int i = 0; i < data3.size(); i++) |
555 | data3[i] = (char)0xDD; |
556 | test3.update(array: data3); |
557 | QCOMPARE(QCA::arrayToHex(test3.final().toByteArray()), |
558 | QStringLiteral("125d7342b9ac11cd91a39af48aa17b4f63f175d3" )); |
559 | |
560 | QCA::MessageAuthenticationCode test4(QStringLiteral("hmac(sha1)" ), QCA::SymmetricKey(), provider); |
561 | QCA::SymmetricKey key4( |
562 | QCA::hexToArray(QStringLiteral("0102030405060708090a0b0c0d0e0f10111213141516171819" ))); |
563 | test4.setup(key4); |
564 | QCA::SecureArray data4(50); |
565 | for (int i = 0; i < data4.size(); i++) |
566 | data4[i] = (char)0xcd; |
567 | test4.update(array: data4); |
568 | QCOMPARE(QCA::arrayToHex(test4.final().toByteArray()), |
569 | QStringLiteral("4c9007f4026250c6bc8414f9bf50c86c2d7235da" )); |
570 | |
571 | QCA::MessageAuthenticationCode test5(QStringLiteral("hmac(sha1)" ), QCA::SymmetricKey(), provider); |
572 | QCA::SymmetricKey key5(QCA::hexToArray(QStringLiteral("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c" ))); |
573 | test5.setup(key5); |
574 | QCA::SecureArray data5("Test With Truncation" ); |
575 | test5.update(array: data5); |
576 | QCOMPARE(QCA::arrayToHex(test5.final().toByteArray()), |
577 | QStringLiteral("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04" )); |
578 | |
579 | QCA::MessageAuthenticationCode test6(QStringLiteral("hmac(sha1)" ), QCA::SymmetricKey(), provider); |
580 | QCA::SymmetricKey key6(80); |
581 | for (int i = 0; i < key6.size(); i++) |
582 | key6[i] = (char)0xAA; |
583 | test6.setup(key6); |
584 | QCA::SecureArray data6("Test Using Larger Than Block-Size Key - Hash Key First" ); |
585 | test6.update(array: data6); |
586 | QCOMPARE(QCA::arrayToHex(test6.final().toByteArray()), |
587 | QStringLiteral("aa4ae5e15272d00e95705637ce8a3b55ed402112" )); |
588 | |
589 | test6.clear(); // this should reuse the same key |
590 | QCA::SecureArray data7("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" ); |
591 | test6.update(array: data7); |
592 | QCOMPARE(QCA::arrayToHex(test6.final().toByteArray()), |
593 | QStringLiteral("e8e99d0f45237d786d6bbaa7965c7808bbff1a91" )); |
594 | } |
595 | } |
596 | } |
597 | |
598 | void MACUnitTest::HMACRMD160() |
599 | { |
600 | QStringList providersToTest; |
601 | providersToTest.append(QStringLiteral("qca-ossl" )); |
602 | providersToTest.append(QStringLiteral("qca-gcrypt" )); |
603 | providersToTest.append(QStringLiteral("qca-botan" )); |
604 | providersToTest.append(QStringLiteral("qca-nss" )); |
605 | |
606 | foreach (const QString provider, providersToTest) { |
607 | if (!QCA::isSupported(features: "hmac(ripemd160)" , provider)) |
608 | QWARN((QStringLiteral("HMAC(RIPEMD160) not supported for " ) + provider).toLocal8Bit().constData()); |
609 | else { |
610 | QCA::MessageAuthenticationCode ripemd160hmacLenTest( |
611 | QStringLiteral("hmac(ripemd160)" ), QCA::SymmetricKey(), provider); |
612 | QCOMPARE(ripemd160hmacLenTest.validKeyLength(0), true); |
613 | QCOMPARE(ripemd160hmacLenTest.validKeyLength(1), true); |
614 | QCOMPARE(ripemd160hmacLenTest.validKeyLength(848888), true); |
615 | QCOMPARE(ripemd160hmacLenTest.validKeyLength(-2), false); |
616 | |
617 | QCA::MessageAuthenticationCode copy = ripemd160hmacLenTest; |
618 | copy.context(); // detach |
619 | |
620 | // These tests are from RFC2286, Section 2. |
621 | QCA::MessageAuthenticationCode test1(QStringLiteral("hmac(ripemd160)" ), QCA::SymmetricKey(), provider); |
622 | QCA::SymmetricKey key1(QCA::hexToArray(QStringLiteral("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" ))); |
623 | test1.setup(key1); |
624 | QCA::SecureArray data1("Hi There" ); |
625 | test1.update(array: data1); |
626 | QCOMPARE(QCA::arrayToHex(test1.final().toByteArray()), |
627 | QStringLiteral("24cb4bd67d20fc1a5d2ed7732dcc39377f0a5668" )); |
628 | |
629 | QCA::MessageAuthenticationCode test2(QStringLiteral("hmac(ripemd160)" ), QCA::SymmetricKey(), provider); |
630 | QCA::SymmetricKey key2(QCA::SecureArray("Jefe" )); |
631 | test2.setup(key2); |
632 | QCA::SecureArray data2("what do ya want for nothing?" ); |
633 | test2.update(array: data2); |
634 | QCOMPARE(QCA::arrayToHex(test2.final().toByteArray()), |
635 | QStringLiteral("dda6c0213a485a9e24f4742064a7f033b43c4069" )); |
636 | |
637 | QCA::MessageAuthenticationCode test3(QStringLiteral("hmac(ripemd160)" ), QCA::SymmetricKey(), provider); |
638 | QCA::SymmetricKey key3(QCA::hexToArray(QStringLiteral("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))); |
639 | test3.setup(key3); |
640 | QCA::SecureArray data3(50); |
641 | for (int i = 0; i < data3.size(); i++) |
642 | data3[i] = (char)0xDD; |
643 | test3.update(array: data3); |
644 | QCOMPARE(QCA::arrayToHex(test3.final().toByteArray()), |
645 | QStringLiteral("b0b105360de759960ab4f35298e116e295d8e7c1" )); |
646 | |
647 | QCA::SymmetricKey key4( |
648 | QCA::hexToArray(QStringLiteral("0102030405060708090a0b0c0d0e0f10111213141516171819" ))); |
649 | QCA::MessageAuthenticationCode test4(QStringLiteral("hmac(ripemd160)" ), key4, provider); |
650 | QCA::SecureArray data4(50); |
651 | for (int i = 0; i < data4.size(); i++) |
652 | data4[i] = (char)0xcd; |
653 | test4.update(array: data4); |
654 | QCOMPARE(QCA::arrayToHex(test4.final().toByteArray()), |
655 | QStringLiteral("d5ca862f4d21d5e610e18b4cf1beb97a4365ecf4" )); |
656 | |
657 | QCA::MessageAuthenticationCode test5(QStringLiteral("hmac(ripemd160)" ), QCA::SymmetricKey(), provider); |
658 | QCA::SymmetricKey key5(QCA::hexToArray(QStringLiteral("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c" ))); |
659 | test5.setup(key5); |
660 | QCA::SecureArray data5("Test With Truncation" ); |
661 | test5.update(array: data5); |
662 | QCOMPARE(QCA::arrayToHex(test5.final().toByteArray()), |
663 | QStringLiteral("7619693978f91d90539ae786500ff3d8e0518e39" )); |
664 | |
665 | QCA::MessageAuthenticationCode test6(QStringLiteral("hmac(ripemd160)" ), QCA::SymmetricKey(), provider); |
666 | QCA::SymmetricKey key6(80); |
667 | for (int i = 0; i < key6.size(); i++) |
668 | key6[i] = (char)0xAA; |
669 | test6.setup(key6); |
670 | QCA::SecureArray data6("Test Using Larger Than Block-Size Key - Hash Key First" ); |
671 | test6.update(array: data6); |
672 | QCOMPARE(QCA::arrayToHex(test6.final().toByteArray()), |
673 | QStringLiteral("6466ca07ac5eac29e1bd523e5ada7605b791fd8b" )); |
674 | |
675 | test6.clear(); // reuse the key |
676 | QCA::SecureArray data7("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" ); |
677 | test6.update(array: data7); |
678 | QCOMPARE(QCA::arrayToHex(test6.final().toByteArray()), |
679 | QStringLiteral("69ea60798d71616cce5fd0871e23754cd75d5a0a" )); |
680 | } |
681 | } |
682 | } |
683 | |
684 | QTEST_MAIN(MACUnitTest) |
685 | |
686 | #include "macunittest.moc" |
687 | |