1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Copyright (C) 2013 Richard J. Moore <rich@kde.org>. |
5 | ** Contact: https://www.qt.io/licensing/ |
6 | ** |
7 | ** This file is part of the QtCore module of the Qt Toolkit. |
8 | ** |
9 | ** $QT_BEGIN_LICENSE:LGPL$ |
10 | ** Commercial License Usage |
11 | ** Licensees holding valid commercial Qt licenses may use this file in |
12 | ** accordance with the commercial license agreement provided with the |
13 | ** Software or, alternatively, in accordance with the terms contained in |
14 | ** a written agreement between you and The Qt Company. For licensing terms |
15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
16 | ** information use the contact form at https://www.qt.io/contact-us. |
17 | ** |
18 | ** GNU Lesser General Public License Usage |
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
20 | ** General Public License version 3 as published by the Free Software |
21 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
22 | ** packaging of this file. Please review the following information to |
23 | ** ensure the GNU Lesser General Public License version 3 requirements |
24 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
25 | ** |
26 | ** GNU General Public License Usage |
27 | ** Alternatively, this file may be used under the terms of the GNU |
28 | ** General Public License version 2.0 or (at your option) the GNU General |
29 | ** Public license version 3 or any later version approved by the KDE Free |
30 | ** Qt Foundation. The licenses are as published by the Free Software |
31 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
32 | ** included in the packaging of this file. Please review the following |
33 | ** information to ensure the GNU General Public License requirements will |
34 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
35 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
36 | ** |
37 | ** $QT_END_LICENSE$ |
38 | ** |
39 | ****************************************************************************/ |
40 | |
41 | #include <qcryptographichash.h> |
42 | #include <qiodevice.h> |
43 | |
44 | #include "../../3rdparty/sha1/sha1.cpp" |
45 | |
46 | #if defined(QT_BOOTSTRAPPED) && !defined(QT_CRYPTOGRAPHICHASH_ONLY_SHA1) |
47 | # error "Are you sure you need the other hashing algorithms besides SHA-1?" |
48 | #endif |
49 | |
50 | #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 |
51 | // qdoc and qmake only need SHA-1 |
52 | #include "../../3rdparty/md5/md5.h" |
53 | #include "../../3rdparty/md5/md5.cpp" |
54 | #include "../../3rdparty/md4/md4.h" |
55 | #include "../../3rdparty/md4/md4.cpp" |
56 | |
57 | typedef unsigned char BitSequence; |
58 | typedef unsigned long long DataLength; |
59 | typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; |
60 | |
61 | #ifdef Q_OS_RTEMS |
62 | # undef ALIGN |
63 | #endif |
64 | |
65 | #include "../../3rdparty/sha3/KeccakSponge.c" |
66 | typedef spongeState hashState; |
67 | |
68 | #include "../../3rdparty/sha3/KeccakNISTInterface.c" |
69 | |
70 | /* |
71 | This lets us choose between SHA3 implementations at build time. |
72 | */ |
73 | typedef spongeState SHA3Context; |
74 | typedef HashReturn (SHA3Init)(hashState *state, int hashbitlen); |
75 | typedef HashReturn (SHA3Update)(hashState *state, const BitSequence *data, DataLength databitlen); |
76 | typedef HashReturn (SHA3Final)(hashState *state, BitSequence *hashval); |
77 | |
78 | #if Q_PROCESSOR_WORDSIZE == 8 // 64 bit version |
79 | |
80 | #include "../../3rdparty/sha3/KeccakF-1600-opt64.c" |
81 | |
82 | static SHA3Init * const sha3Init = Init; |
83 | static SHA3Update * const sha3Update = Update; |
84 | static SHA3Final * const sha3Final = Final; |
85 | |
86 | #else // 32 bit optimised fallback |
87 | |
88 | #include "../../3rdparty/sha3/KeccakF-1600-opt32.c" |
89 | |
90 | static SHA3Init * const sha3Init = Init; |
91 | static SHA3Update * const sha3Update = Update; |
92 | static SHA3Final * const sha3Final = Final; |
93 | |
94 | #endif |
95 | |
96 | // Header from rfc6234 |
97 | #include "../../3rdparty/rfc6234/sha.h" |
98 | |
99 | /* |
100 | These 2 functions replace macros of the same name in sha224-256.c and |
101 | sha384-512.c. Originally, these macros relied on a global static 'addTemp' |
102 | variable. We do not want this for 2 reasons: |
103 | |
104 | 1. since we are including the sources directly, the declaration of the 2 conflict |
105 | |
106 | 2. static variables are not thread-safe, we do not want multiple threads |
107 | computing a hash to corrupt one another |
108 | */ |
109 | static int SHA224_256AddLength(SHA256Context *context, unsigned int length); |
110 | static int SHA384_512AddLength(SHA512Context *context, unsigned int length); |
111 | |
112 | // Sources from rfc6234, with 4 modifications: |
113 | // sha224-256.c - commented out 'static uint32_t addTemp;' on line 68 |
114 | // sha224-256.c - appended 'M' to the SHA224_256AddLength macro on line 70 |
115 | #include "../../3rdparty/rfc6234/sha224-256.c" |
116 | // sha384-512.c - commented out 'static uint64_t addTemp;' on line 302 |
117 | // sha384-512.c - appended 'M' to the SHA224_256AddLength macro on line 304 |
118 | #include "../../3rdparty/rfc6234/sha384-512.c" |
119 | |
120 | static inline int SHA224_256AddLength(SHA256Context *context, unsigned int length) |
121 | { |
122 | uint32_t addTemp; |
123 | return SHA224_256AddLengthM(context, length); |
124 | } |
125 | static inline int SHA384_512AddLength(SHA512Context *context, unsigned int length) |
126 | { |
127 | uint64_t addTemp; |
128 | return SHA384_512AddLengthM(context, length); |
129 | } |
130 | |
131 | #if QT_CONFIG(system_libb2) |
132 | #include <blake2.h> |
133 | #else |
134 | #include "../../3rdparty/blake2/src/blake2b-ref.c" |
135 | #include "../../3rdparty/blake2/src/blake2s-ref.c" |
136 | #endif |
137 | #endif // QT_CRYPTOGRAPHICHASH_ONLY_SHA1 |
138 | |
139 | QT_BEGIN_NAMESPACE |
140 | |
141 | class QCryptographicHashPrivate |
142 | { |
143 | public: |
144 | QCryptographicHash::Algorithm method; |
145 | union { |
146 | Sha1State sha1Context; |
147 | #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 |
148 | MD5Context md5Context; |
149 | md4_context md4Context; |
150 | SHA224Context sha224Context; |
151 | SHA256Context sha256Context; |
152 | SHA384Context sha384Context; |
153 | SHA512Context sha512Context; |
154 | SHA3Context sha3Context; |
155 | blake2b_state blake2bContext; |
156 | blake2s_state blake2sContext; |
157 | #endif |
158 | }; |
159 | #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 |
160 | enum class Sha3Variant |
161 | { |
162 | Sha3, |
163 | Keccak |
164 | }; |
165 | void sha3Finish(int bitCount, Sha3Variant sha3Variant); |
166 | #endif |
167 | QByteArray result; |
168 | }; |
169 | |
170 | #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 |
171 | void QCryptographicHashPrivate::sha3Finish(int bitCount, Sha3Variant sha3Variant) |
172 | { |
173 | /* |
174 | FIPS 202 ยง6.1 defines SHA-3 in terms of calculating the Keccak function |
175 | over the original message with the two-bit suffix "01" appended to it. |
176 | This variable stores that suffix (and it's fed into the calculations |
177 | when the hash is returned to users). |
178 | |
179 | Only 2 bits of this variable are actually used (see the call to sha3Update |
180 | below). The Keccak implementation we're using will actually use the |
181 | *leftmost* 2 bits, and interpret them right-to-left. In other words, the |
182 | bits must appear in order of *increasing* significance; and as the two most |
183 | significant bits of the byte -- the rightmost 6 are ignored. (Yes, this |
184 | seems self-contradictory, but it's the way it is...) |
185 | |
186 | Overall, this means: |
187 | * the leftmost two bits must be "10" (not "01"!); |
188 | * we don't care what the other six bits are set to (they can be set to |
189 | any value), but we arbitrarily set them to 0; |
190 | |
191 | and for an unsigned char this gives us 0b10'00'00'00, or 0x80. |
192 | */ |
193 | static const unsigned char sha3FinalSuffix = 0x80; |
194 | |
195 | result.resize(bitCount / 8); |
196 | |
197 | SHA3Context copy = sha3Context; |
198 | |
199 | switch (sha3Variant) { |
200 | case Sha3Variant::Sha3: |
201 | sha3Update(©, reinterpret_cast<const BitSequence *>(&sha3FinalSuffix), 2); |
202 | break; |
203 | case Sha3Variant::Keccak: |
204 | break; |
205 | } |
206 | |
207 | sha3Final(©, reinterpret_cast<BitSequence *>(result.data())); |
208 | } |
209 | #endif |
210 | |
211 | /*! |
212 | \class QCryptographicHash |
213 | \inmodule QtCore |
214 | |
215 | \brief The QCryptographicHash class provides a way to generate cryptographic hashes. |
216 | |
217 | \since 4.3 |
218 | |
219 | \ingroup tools |
220 | \reentrant |
221 | |
222 | QCryptographicHash can be used to generate cryptographic hashes of binary or text data. |
223 | |
224 | Refer to the documentation of the \l QCryptographicHash::Algorithm enum for a |
225 | list of the supported algorithms. |
226 | */ |
227 | |
228 | /*! |
229 | \enum QCryptographicHash::Algorithm |
230 | |
231 | \note In Qt versions before 5.9, when asked to generate a SHA3 hash sum, |
232 | QCryptographicHash actually calculated Keccak. If you need compatibility with |
233 | SHA-3 hashes produced by those versions of Qt, use the \c{Keccak_} |
234 | enumerators. Alternatively, if source compatibility is required, define the |
235 | macro \c QT_SHA3_KECCAK_COMPAT. |
236 | |
237 | \value Md4 Generate an MD4 hash sum |
238 | \value Md5 Generate an MD5 hash sum |
239 | \value Sha1 Generate an SHA-1 hash sum |
240 | \value Sha224 Generate an SHA-224 hash sum (SHA-2). Introduced in Qt 5.0 |
241 | \value Sha256 Generate an SHA-256 hash sum (SHA-2). Introduced in Qt 5.0 |
242 | \value Sha384 Generate an SHA-384 hash sum (SHA-2). Introduced in Qt 5.0 |
243 | \value Sha512 Generate an SHA-512 hash sum (SHA-2). Introduced in Qt 5.0 |
244 | \value Sha3_224 Generate an SHA3-224 hash sum. Introduced in Qt 5.1 |
245 | \value Sha3_256 Generate an SHA3-256 hash sum. Introduced in Qt 5.1 |
246 | \value Sha3_384 Generate an SHA3-384 hash sum. Introduced in Qt 5.1 |
247 | \value Sha3_512 Generate an SHA3-512 hash sum. Introduced in Qt 5.1 |
248 | \value Keccak_224 Generate a Keccak-224 hash sum. Introduced in Qt 5.9.2 |
249 | \value Keccak_256 Generate a Keccak-256 hash sum. Introduced in Qt 5.9.2 |
250 | \value Keccak_384 Generate a Keccak-384 hash sum. Introduced in Qt 5.9.2 |
251 | \value Keccak_512 Generate a Keccak-512 hash sum. Introduced in Qt 5.9.2 |
252 | \value Blake2b_160 Generate a BLAKE2b-160 hash sum. Introduced in Qt 6.0 |
253 | \value Blake2b_256 Generate a BLAKE2b-256 hash sum. Introduced in Qt 6.0 |
254 | \value Blake2b_384 Generate a BLAKE2b-384 hash sum. Introduced in Qt 6.0 |
255 | \value Blake2b_512 Generate a BLAKE2b-512 hash sum. Introduced in Qt 6.0 |
256 | \value Blake2s_128 Generate a BLAKE2s-128 hash sum. Introduced in Qt 6.0 |
257 | \value Blake2s_160 Generate a BLAKE2s-160 hash sum. Introduced in Qt 6.0 |
258 | \value Blake2s_224 Generate a BLAKE2s-224 hash sum. Introduced in Qt 6.0 |
259 | \value Blake2s_256 Generate a BLAKE2s-256 hash sum. Introduced in Qt 6.0 |
260 | \omitvalue RealSha3_224 |
261 | \omitvalue RealSha3_256 |
262 | \omitvalue RealSha3_384 |
263 | \omitvalue RealSha3_512 |
264 | */ |
265 | |
266 | /*! |
267 | Constructs an object that can be used to create a cryptographic hash from data using \a method. |
268 | */ |
269 | QCryptographicHash::QCryptographicHash(Algorithm method) |
270 | : d(new QCryptographicHashPrivate) |
271 | { |
272 | d->method = method; |
273 | reset(); |
274 | } |
275 | |
276 | /*! |
277 | Destroys the object. |
278 | */ |
279 | QCryptographicHash::~QCryptographicHash() |
280 | { |
281 | delete d; |
282 | } |
283 | |
284 | /*! |
285 | Resets the object. |
286 | */ |
287 | void QCryptographicHash::reset() |
288 | { |
289 | switch (d->method) { |
290 | case Sha1: |
291 | new (&d->sha1Context) Sha1State; |
292 | sha1InitState(&d->sha1Context); |
293 | break; |
294 | #ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 |
295 | default: |
296 | Q_ASSERT_X(false, "QCryptographicHash" , "Method not compiled in" ); |
297 | Q_UNREACHABLE(); |
298 | break; |
299 | #else |
300 | case Md4: |
301 | new (&d->md4Context) md4_context; |
302 | md4_init(&d->md4Context); |
303 | break; |
304 | case Md5: |
305 | new (&d->md5Context) MD5Context; |
306 | MD5Init(&d->md5Context); |
307 | break; |
308 | case Sha224: |
309 | new (&d->sha224Context) SHA224Context; |
310 | SHA224Reset(&d->sha224Context); |
311 | break; |
312 | case Sha256: |
313 | new (&d->sha256Context) SHA256Context; |
314 | SHA256Reset(&d->sha256Context); |
315 | break; |
316 | case Sha384: |
317 | new (&d->sha384Context) SHA384Context; |
318 | SHA384Reset(&d->sha384Context); |
319 | break; |
320 | case Sha512: |
321 | new (&d->sha512Context) SHA512Context; |
322 | SHA512Reset(&d->sha512Context); |
323 | break; |
324 | case RealSha3_224: |
325 | case Keccak_224: |
326 | case RealSha3_256: |
327 | case Keccak_256: |
328 | case RealSha3_384: |
329 | case Keccak_384: |
330 | case RealSha3_512: |
331 | case Keccak_512: |
332 | new (&d->sha3Context) SHA3Context; |
333 | sha3Init(&d->sha3Context, hashLength(d->method) * 8); |
334 | break; |
335 | case Blake2b_160: |
336 | case Blake2b_256: |
337 | case Blake2b_384: |
338 | case Blake2b_512: |
339 | new (&d->blake2bContext) blake2b_state; |
340 | blake2b_init(&d->blake2bContext, hashLength(d->method)); |
341 | break; |
342 | case Blake2s_128: |
343 | case Blake2s_160: |
344 | case Blake2s_224: |
345 | case Blake2s_256: |
346 | new (&d->blake2sContext) blake2s_state; |
347 | blake2s_init(&d->blake2sContext, hashLength(d->method)); |
348 | break; |
349 | #endif |
350 | } |
351 | d->result.clear(); |
352 | } |
353 | |
354 | /*! |
355 | Adds the first \a length chars of \a data to the cryptographic |
356 | hash. |
357 | */ |
358 | void QCryptographicHash::addData(const char *data, qsizetype length) |
359 | { |
360 | Q_ASSERT(length >= 0); |
361 | |
362 | #if QT_POINTER_SIZE == 8 |
363 | // feed the data UINT_MAX bytes at a time, as some of the methods below |
364 | // take a uint (of course, feeding more than 4G of data into the hashing |
365 | // functions will be pretty slow anyway) |
366 | qsizetype remaining = length; |
367 | while (remaining) { |
368 | length = qMin(qsizetype(std::numeric_limits<uint>::max()), remaining); |
369 | remaining -= length; |
370 | #else |
371 | { |
372 | #endif |
373 | switch (d->method) { |
374 | case Sha1: |
375 | sha1Update(&d->sha1Context, (const unsigned char *)data, length); |
376 | break; |
377 | #ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 |
378 | default: |
379 | Q_ASSERT_X(false, "QCryptographicHash" , "Method not compiled in" ); |
380 | Q_UNREACHABLE(); |
381 | break; |
382 | #else |
383 | case Md4: |
384 | md4_update(&d->md4Context, (const unsigned char *)data, length); |
385 | break; |
386 | case Md5: |
387 | MD5Update(&d->md5Context, (const unsigned char *)data, length); |
388 | break; |
389 | case Sha224: |
390 | SHA224Input(&d->sha224Context, reinterpret_cast<const unsigned char *>(data), length); |
391 | break; |
392 | case Sha256: |
393 | SHA256Input(&d->sha256Context, reinterpret_cast<const unsigned char *>(data), length); |
394 | break; |
395 | case Sha384: |
396 | SHA384Input(&d->sha384Context, reinterpret_cast<const unsigned char *>(data), length); |
397 | break; |
398 | case Sha512: |
399 | SHA512Input(&d->sha512Context, reinterpret_cast<const unsigned char *>(data), length); |
400 | break; |
401 | case RealSha3_224: |
402 | case Keccak_224: |
403 | sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), uint64_t(length) * 8); |
404 | break; |
405 | case RealSha3_256: |
406 | case Keccak_256: |
407 | sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), uint64_t(length) * 8); |
408 | break; |
409 | case RealSha3_384: |
410 | case Keccak_384: |
411 | sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), uint64_t(length) * 8); |
412 | break; |
413 | case RealSha3_512: |
414 | case Keccak_512: |
415 | sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), uint64_t(length) * 8); |
416 | break; |
417 | case Blake2b_160: |
418 | case Blake2b_256: |
419 | case Blake2b_384: |
420 | case Blake2b_512: |
421 | blake2b_update(&d->blake2bContext, reinterpret_cast<const uint8_t *>(data), length); |
422 | break; |
423 | case Blake2s_128: |
424 | case Blake2s_160: |
425 | case Blake2s_224: |
426 | case Blake2s_256: |
427 | blake2s_update(&d->blake2sContext, reinterpret_cast<const uint8_t *>(data), length); |
428 | break; |
429 | #endif |
430 | } |
431 | } |
432 | d->result.clear(); |
433 | } |
434 | |
435 | /*! |
436 | \overload addData() |
437 | */ |
438 | void QCryptographicHash::addData(const QByteArray &data) |
439 | { |
440 | addData(data.constData(), data.length()); |
441 | } |
442 | |
443 | /*! |
444 | Reads the data from the open QIODevice \a device until it ends |
445 | and hashes it. Returns \c true if reading was successful. |
446 | \since 5.0 |
447 | */ |
448 | bool QCryptographicHash::addData(QIODevice *device) |
449 | { |
450 | if (!device->isReadable()) |
451 | return false; |
452 | |
453 | if (!device->isOpen()) |
454 | return false; |
455 | |
456 | char buffer[1024]; |
457 | int length; |
458 | |
459 | while ((length = device->read(buffer, sizeof(buffer))) > 0) |
460 | addData(buffer, length); |
461 | |
462 | return device->atEnd(); |
463 | } |
464 | |
465 | |
466 | /*! |
467 | Returns the final hash value. |
468 | |
469 | \sa QByteArray::toHex() |
470 | */ |
471 | QByteArray QCryptographicHash::result() const |
472 | { |
473 | if (!d->result.isEmpty()) |
474 | return d->result; |
475 | |
476 | switch (d->method) { |
477 | case Sha1: { |
478 | Sha1State copy = d->sha1Context; |
479 | d->result.resize(20); |
480 | sha1FinalizeState(©); |
481 | sha1ToHash(©, (unsigned char *)d->result.data()); |
482 | break; |
483 | } |
484 | #ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 |
485 | default: |
486 | Q_ASSERT_X(false, "QCryptographicHash" , "Method not compiled in" ); |
487 | Q_UNREACHABLE(); |
488 | break; |
489 | #else |
490 | case Md4: { |
491 | md4_context copy = d->md4Context; |
492 | d->result.resize(MD4_RESULTLEN); |
493 | md4_final(©, (unsigned char *)d->result.data()); |
494 | break; |
495 | } |
496 | case Md5: { |
497 | MD5Context copy = d->md5Context; |
498 | d->result.resize(16); |
499 | MD5Final(©, (unsigned char *)d->result.data()); |
500 | break; |
501 | } |
502 | case Sha224: { |
503 | SHA224Context copy = d->sha224Context; |
504 | d->result.resize(SHA224HashSize); |
505 | SHA224Result(©, reinterpret_cast<unsigned char *>(d->result.data())); |
506 | break; |
507 | } |
508 | case Sha256: { |
509 | SHA256Context copy = d->sha256Context; |
510 | d->result.resize(SHA256HashSize); |
511 | SHA256Result(©, reinterpret_cast<unsigned char *>(d->result.data())); |
512 | break; |
513 | } |
514 | case Sha384: { |
515 | SHA384Context copy = d->sha384Context; |
516 | d->result.resize(SHA384HashSize); |
517 | SHA384Result(©, reinterpret_cast<unsigned char *>(d->result.data())); |
518 | break; |
519 | } |
520 | case Sha512: { |
521 | SHA512Context copy = d->sha512Context; |
522 | d->result.resize(SHA512HashSize); |
523 | SHA512Result(©, reinterpret_cast<unsigned char *>(d->result.data())); |
524 | break; |
525 | } |
526 | case RealSha3_224: { |
527 | d->sha3Finish(224, QCryptographicHashPrivate::Sha3Variant::Sha3); |
528 | break; |
529 | } |
530 | case RealSha3_256: { |
531 | d->sha3Finish(256, QCryptographicHashPrivate::Sha3Variant::Sha3); |
532 | break; |
533 | } |
534 | case RealSha3_384: { |
535 | d->sha3Finish(384, QCryptographicHashPrivate::Sha3Variant::Sha3); |
536 | break; |
537 | } |
538 | case RealSha3_512: { |
539 | d->sha3Finish(512, QCryptographicHashPrivate::Sha3Variant::Sha3); |
540 | break; |
541 | } |
542 | case Keccak_224: { |
543 | d->sha3Finish(224, QCryptographicHashPrivate::Sha3Variant::Keccak); |
544 | break; |
545 | } |
546 | case Keccak_256: { |
547 | d->sha3Finish(256, QCryptographicHashPrivate::Sha3Variant::Keccak); |
548 | break; |
549 | } |
550 | case Keccak_384: { |
551 | d->sha3Finish(384, QCryptographicHashPrivate::Sha3Variant::Keccak); |
552 | break; |
553 | } |
554 | case Keccak_512: { |
555 | d->sha3Finish(512, QCryptographicHashPrivate::Sha3Variant::Keccak); |
556 | break; |
557 | } |
558 | case Blake2b_160: |
559 | case Blake2b_256: |
560 | case Blake2b_384: |
561 | case Blake2b_512: { |
562 | const auto length = hashLength(d->method); |
563 | blake2b_state copy = d->blake2bContext; |
564 | d->result.resize(length); |
565 | blake2b_final(©, reinterpret_cast<uint8_t *>(d->result.data()), length); |
566 | break; |
567 | } |
568 | case Blake2s_128: |
569 | case Blake2s_160: |
570 | case Blake2s_224: |
571 | case Blake2s_256: { |
572 | const auto length = hashLength(d->method); |
573 | blake2s_state copy = d->blake2sContext; |
574 | d->result.resize(length); |
575 | blake2s_final(©, reinterpret_cast<uint8_t *>(d->result.data()), length); |
576 | break; |
577 | } |
578 | #endif |
579 | } |
580 | return d->result; |
581 | } |
582 | |
583 | /*! |
584 | Returns the hash of \a data using \a method. |
585 | */ |
586 | QByteArray QCryptographicHash::hash(const QByteArray &data, Algorithm method) |
587 | { |
588 | QCryptographicHash hash(method); |
589 | hash.addData(data); |
590 | return hash.result(); |
591 | } |
592 | |
593 | /*! |
594 | Returns the size of the output of the selected hash \a method in bytes. |
595 | |
596 | \since 5.12 |
597 | */ |
598 | int QCryptographicHash::hashLength(QCryptographicHash::Algorithm method) |
599 | { |
600 | switch (method) { |
601 | case QCryptographicHash::Sha1: |
602 | return 20; |
603 | #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 |
604 | case QCryptographicHash::Md4: |
605 | return 16; |
606 | case QCryptographicHash::Md5: |
607 | return 16; |
608 | case QCryptographicHash::Sha224: |
609 | return SHA224HashSize; |
610 | case QCryptographicHash::Sha256: |
611 | return SHA256HashSize; |
612 | case QCryptographicHash::Sha384: |
613 | return SHA384HashSize; |
614 | case QCryptographicHash::Sha512: |
615 | return SHA512HashSize; |
616 | case QCryptographicHash::Blake2s_128: |
617 | return 128 / 8; |
618 | case QCryptographicHash::Blake2b_160: |
619 | case QCryptographicHash::Blake2s_160: |
620 | return 160 / 8; |
621 | case QCryptographicHash::RealSha3_224: |
622 | case QCryptographicHash::Keccak_224: |
623 | case QCryptographicHash::Blake2s_224: |
624 | return 224 / 8; |
625 | case QCryptographicHash::RealSha3_256: |
626 | case QCryptographicHash::Keccak_256: |
627 | case QCryptographicHash::Blake2b_256: |
628 | case QCryptographicHash::Blake2s_256: |
629 | return 256 / 8; |
630 | case QCryptographicHash::RealSha3_384: |
631 | case QCryptographicHash::Keccak_384: |
632 | case QCryptographicHash::Blake2b_384: |
633 | return 384 / 8; |
634 | case QCryptographicHash::RealSha3_512: |
635 | case QCryptographicHash::Keccak_512: |
636 | case QCryptographicHash::Blake2b_512: |
637 | return 512 / 8; |
638 | #endif |
639 | } |
640 | return 0; |
641 | } |
642 | |
643 | QT_END_NAMESPACE |
644 | |
645 | #ifndef QT_NO_QOBJECT |
646 | #include "moc_qcryptographichash.cpp" |
647 | #endif |
648 | |