7#include <qcryptographichash.h>
8#include <qmessageauthenticationcode.h>
10#include <QtCore/private/qsmallbytearray_p.h>
13#include <private/qlocking_p.h>
19#include "../../3rdparty/sha1/sha1.cpp"
22#include "../../3rdparty/rfc6234/sha.h"
24#if !QT_CONFIG(openssl_hash)
25#include "../../3rdparty/md5/md5.h"
26#include "../../3rdparty/md5/md5.cpp"
27#include "../../3rdparty/md4/md4.h"
28#include "../../3rdparty/md4/md4.cpp"
39#include "../../3rdparty/sha3/KeccakSponge.c"
42#include "../../3rdparty/sha3/KeccakNISTInterface.c"
45
46
48typedef HashReturn (SHA3Init)(
hashState *state,
int hashbitlen);
52#if Q_PROCESSOR_WORDSIZE == 8
54#include "../../3rdparty/sha3/KeccakF-1600-opt64.c"
56Q_CONSTINIT
static SHA3Init *
const sha3Init = Init;
57Q_CONSTINIT
static SHA3Update *
const sha3Update = Update;
58Q_CONSTINIT
static SHA3Final *
const sha3Final = Final;
62#include "../../3rdparty/sha3/KeccakF-1600-opt32.c"
64Q_CONSTINIT
static SHA3Init *
const sha3Init = Init;
65Q_CONSTINIT
static SHA3Update *
const sha3Update = Update;
66Q_CONSTINIT
static SHA3Final *
const sha3Final = Final;
70#if !QT_CONFIG(openssl_hash)
72
73
74
75
76
77
78
79
80
81static int SHA224_256AddLength(SHA256Context *context,
unsigned int length);
82static int SHA384_512AddLength(SHA512Context *context,
unsigned int length);
87#include "../../3rdparty/rfc6234/sha224-256.c"
90#include "../../3rdparty/rfc6234/sha384-512.c"
92static inline int SHA224_256AddLength(SHA256Context *context,
unsigned int length)
95 return SHA224_256AddLengthM(context, length);
97static inline int SHA384_512AddLength(SHA512Context *context,
unsigned int length)
100 return SHA384_512AddLengthM(context, length);
104#if QT_CONFIG(system_libb2)
108QT_WARNING_DISABLE_CLANG(
"-Wunused-function")
109QT_WARNING_DISABLE_GCC(
"-Wunused-function")
110QT_WARNING_DISABLE_MSVC(4505)
111#include "../../3rdparty/blake2/src/blake2b-ref.c"
112#include "../../3rdparty/blake2/src/blake2s-ref.c"
116#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(openssl_hash)
117#define USING_OPENSSL30
118#include <openssl/crypto.h>
119#include <openssl/evp.h>
120#include <openssl/provider.h>
128#define CASE(Enum, Size)
129 case QCryptographicHash:: Enum :
135 CASE(Sha224, SHA224HashSize);
136 CASE(Sha256, SHA256HashSize);
137 CASE(Sha384, SHA384HashSize);
138 CASE(Sha512, SHA512HashSize);
139 CASE(Blake2s_128, 128 / 8);
140 case QCryptographicHash::Blake2b_160:
141 case QCryptographicHash::Blake2s_160:
143 case QCryptographicHash::RealSha3_224:
144 case QCryptographicHash::Keccak_224:
145 case QCryptographicHash::Blake2s_224:
147 case QCryptographicHash::RealSha3_256:
148 case QCryptographicHash::Keccak_256:
149 case QCryptographicHash::Blake2b_256:
150 case QCryptographicHash::Blake2s_256:
152 case QCryptographicHash::RealSha3_384:
153 case QCryptographicHash::Keccak_384:
154 case QCryptographicHash::Blake2b_384:
156 case QCryptographicHash::RealSha3_512:
157 case QCryptographicHash::Keccak_512:
158 case QCryptographicHash::Blake2b_512:
161 case QCryptographicHash::NumAlgorithms: ;
171 using A = QCryptographicHash::Algorithm;
172 for (
int i = 0; i < A::NumAlgorithms; ++i)
173 result =
std::max(result, hashLengthInternal(A(i)));
177using HashResult = QSmallByteArray<maxHashLength()>;
179#ifdef USING_OPENSSL30
180static constexpr const char * methodToName(QCryptographicHash::Algorithm method)
noexcept
183#define CASE(Enum, Name)
184 case QCryptographicHash:: Enum :
190 CASE(Sha224,
"SHA224");
191 CASE(Sha256,
"SHA256");
192 CASE(Sha384,
"SHA384");
193 CASE(Sha512,
"SHA512");
194 CASE(RealSha3_224,
"SHA3-224");
195 CASE(RealSha3_256,
"SHA3-256");
196 CASE(RealSha3_384,
"SHA3-384");
197 CASE(RealSha3_512,
"SHA3-512");
198 CASE(Blake2b_512,
"BLAKE2B512");
199 CASE(Blake2s_256,
"BLAKE2S256");
201 CASE(Keccak_224,
nullptr);
202 CASE(Keccak_256,
nullptr);
203 CASE(Keccak_384,
nullptr);
204 CASE(Keccak_512,
nullptr);
205 CASE(Blake2b_160,
nullptr);
206 CASE(Blake2b_256,
nullptr);
207 CASE(Blake2b_384,
nullptr);
208 CASE(Blake2s_128,
nullptr);
209 CASE(Blake2s_160,
nullptr);
210 CASE(Blake2s_224,
nullptr);
211 CASE(NumAlgorithms,
nullptr);
218
219
220
221
222
223
224
225
226
227
228static void ensureDefaultProviderLoaded()
230 static const bool loaded = OSSL_PROVIDER_try_load(
nullptr,
"default", 1);
235struct OSSL_LIB_CTX_deleter {
236 void operator()(OSSL_LIB_CTX *ctx)
const noexcept {
237 OSSL_LIB_CTX_free(ctx);
240using OSSL_LIB_CTX_ptr = std::unique_ptr<OSSL_LIB_CTX, OSSL_LIB_CTX_deleter>;
244
245
246
247
248
249
250static OSSL_LIB_CTX *legacyProviderContext()
252 static const OSSL_LIB_CTX_ptr ctx = [] {
253 OSSL_LIB_CTX_ptr ctx(OSSL_LIB_CTX_new());
257 const bool configLoaded = OSSL_LIB_CTX_load_config(ctx.get(),
nullptr);
258 Q_UNUSED(configLoaded);
259 if (!OSSL_PROVIDER_load(ctx.get(),
"legacy"))
277 state.destroy(method);
293#ifdef USING_OPENSSL30
312 void reset()
noexcept;
320#ifdef USING_OPENSSL30
329#ifdef USING_OPENSSL30
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376 static const unsigned char sha3FinalSuffix = 0x80;
378 switch (sha3Variant) {
380 sha3Update(&ctx,
reinterpret_cast<
const BitSequence *>(&sha3FinalSuffix), 2);
386 sha3Final(&ctx, result.data());
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
446
447
448QCryptographicHash::QCryptographicHash(Algorithm method)
449 : d(
new QCryptographicHashPrivate{method})
454
455
456
457
458
459
460
461
462
463
466
467
468QCryptographicHash::~QCryptographicHash()
474
475
476
477
478
479
480
481
482
483
486
487
488
489
492
493
494void QCryptographicHash::reset()
noexcept
500
501
502
503
504QCryptographicHash::Algorithm QCryptographicHash::algorithm()
const noexcept
509#ifdef USING_OPENSSL30
511QCryptographicHashPrivate::State::State(QCryptographicHash::Algorithm method)
514 case QCryptographicHash::Keccak_224:
515 case QCryptographicHash::Keccak_256:
516 case QCryptographicHash::Keccak_384:
517 case QCryptographicHash::Keccak_512:
518 new (&sha3Context) SHA3Context;
521 case QCryptographicHash::Blake2b_160:
522 case QCryptographicHash::Blake2b_256:
523 case QCryptographicHash::Blake2b_384:
524 new (&blake2bContext) blake2b_state;
527 case QCryptographicHash::Blake2s_128:
528 case QCryptographicHash::Blake2s_160:
529 case QCryptographicHash::Blake2s_224:
530 new (&blake2sContext) blake2s_state;
533 case QCryptographicHash::Sha1:
534 case QCryptographicHash::Md4:
535 case QCryptographicHash::Md5:
536 case QCryptographicHash::Sha224:
537 case QCryptographicHash::Sha256:
538 case QCryptographicHash::Sha384:
539 case QCryptographicHash::Sha512:
540 case QCryptographicHash::RealSha3_224:
541 case QCryptographicHash::RealSha3_256:
542 case QCryptographicHash::RealSha3_384:
543 case QCryptographicHash::RealSha3_512:
544 case QCryptographicHash::Blake2b_512:
545 case QCryptographicHash::Blake2s_256:
546 new (&evp) EVP(method);
548 case QCryptographicHash::NumAlgorithms:
553void QCryptographicHashPrivate::State::destroy(QCryptographicHash::Algorithm method)
556 case QCryptographicHash::Keccak_224:
557 case QCryptographicHash::Keccak_256:
558 case QCryptographicHash::Keccak_384:
559 case QCryptographicHash::Keccak_512:
560 case QCryptographicHash::Blake2b_160:
561 case QCryptographicHash::Blake2b_256:
562 case QCryptographicHash::Blake2b_384:
563 case QCryptographicHash::Blake2s_128:
564 case QCryptographicHash::Blake2s_160:
565 case QCryptographicHash::Blake2s_224:
567 case QCryptographicHash::Sha1:
568 case QCryptographicHash::Md4:
569 case QCryptographicHash::Md5:
570 case QCryptographicHash::Sha224:
571 case QCryptographicHash::Sha256:
572 case QCryptographicHash::Sha384:
573 case QCryptographicHash::Sha512:
574 case QCryptographicHash::RealSha3_224:
575 case QCryptographicHash::RealSha3_256:
576 case QCryptographicHash::RealSha3_384:
577 case QCryptographicHash::RealSha3_512:
578 case QCryptographicHash::Blake2b_512:
579 case QCryptographicHash::Blake2s_256:
582 case QCryptographicHash::NumAlgorithms:
587QCryptographicHashPrivate::EVP::EVP(QCryptographicHash::Algorithm method)
588 : initializationFailed{
true}
590 OSSL_LIB_CTX *fetchCtx =
nullptr;
591 if (method == QCryptographicHash::Md4) {
592 fetchCtx = legacyProviderContext();
596 ensureDefaultProviderLoaded();
599 context = EVP_MD_CTX_ptr(EVP_MD_CTX_new());
606
607
608
609
610
611 algorithm = EVP_MD_ptr{EVP_MD_fetch(fetchCtx, methodToName(method),
"-fips")};
616 initializationFailed = !EVP_DigestInit_ex(context.get(), algorithm.get(),
nullptr);
624 case QCryptographicHash::Sha1:
625 new (&sha1Context) Sha1State;
627 case QCryptographicHash::Md4:
628 new (&md4Context) md4_context;
630 case QCryptographicHash::Md5:
631 new (&md5Context) MD5Context;
633 case QCryptographicHash::Sha224:
636 case QCryptographicHash::Sha256:
639 case QCryptographicHash::Sha384:
642 case QCryptographicHash::Sha512:
645 case QCryptographicHash::RealSha3_224:
646 case QCryptographicHash::Keccak_224:
647 case QCryptographicHash::RealSha3_256:
648 case QCryptographicHash::Keccak_256:
649 case QCryptographicHash::RealSha3_384:
650 case QCryptographicHash::Keccak_384:
651 case QCryptographicHash::RealSha3_512:
652 case QCryptographicHash::Keccak_512:
655 case QCryptographicHash::Blake2b_160:
656 case QCryptographicHash::Blake2b_256:
657 case QCryptographicHash::Blake2b_384:
658 case QCryptographicHash::Blake2b_512:
659 new (&blake2bContext) blake2b_state;
661 case QCryptographicHash::Blake2s_128:
662 case QCryptographicHash::Blake2s_160:
663 case QCryptographicHash::Blake2s_224:
664 case QCryptographicHash::Blake2s_256:
665 new (&blake2sContext) blake2s_state;
667 case QCryptographicHash::NumAlgorithms:
675 static_assert(std::is_trivially_destructible_v<State>);
685#ifdef USING_OPENSSL30
687void QCryptographicHashPrivate::State::reset(QCryptographicHash::Algorithm method)
noexcept
690 case QCryptographicHash::Keccak_224:
691 case QCryptographicHash::Keccak_256:
692 case QCryptographicHash::Keccak_384:
693 case QCryptographicHash::Keccak_512:
694 sha3Init(&sha3Context, hashLengthInternal(method) * 8);
696 case QCryptographicHash::Blake2b_160:
697 case QCryptographicHash::Blake2b_256:
698 case QCryptographicHash::Blake2b_384:
699 blake2b_init(&blake2bContext, hashLengthInternal(method));
701 case QCryptographicHash::Blake2s_128:
702 case QCryptographicHash::Blake2s_160:
703 case QCryptographicHash::Blake2s_224:
704 blake2s_init(&blake2sContext, hashLengthInternal(method));
706 case QCryptographicHash::Sha1:
707 case QCryptographicHash::Md4:
708 case QCryptographicHash::Md5:
709 case QCryptographicHash::Sha224:
710 case QCryptographicHash::Sha256:
711 case QCryptographicHash::Sha384:
712 case QCryptographicHash::Sha512:
713 case QCryptographicHash::RealSha3_224:
714 case QCryptographicHash::RealSha3_256:
715 case QCryptographicHash::RealSha3_384:
716 case QCryptographicHash::RealSha3_512:
717 case QCryptographicHash::Blake2b_512:
718 case QCryptographicHash::Blake2s_256:
721 case QCryptographicHash::NumAlgorithms:
726void QCryptographicHashPrivate::EVP::reset()
noexcept
728 if (!initializationFailed) {
732 EVP_MD_CTX_reset(context.get());
733 initializationFailed = !EVP_DigestInit_ex(context.get(), algorithm.get(),
nullptr);
743 case QCryptographicHash::Sha1:
744 sha1InitState(&sha1Context);
746 case QCryptographicHash::Md4:
747 md4_init(&md4Context);
749 case QCryptographicHash::Md5:
750 MD5Init(&md5Context);
752 case QCryptographicHash::Sha224:
755 case QCryptographicHash::Sha256:
758 case QCryptographicHash::Sha384:
761 case QCryptographicHash::Sha512:
764 case QCryptographicHash::RealSha3_224:
765 case QCryptographicHash::Keccak_224:
766 case QCryptographicHash::RealSha3_256:
767 case QCryptographicHash::Keccak_256:
768 case QCryptographicHash::RealSha3_384:
769 case QCryptographicHash::Keccak_384:
770 case QCryptographicHash::RealSha3_512:
771 case QCryptographicHash::Keccak_512:
772 sha3Init(&
sha3Context, hashLengthInternal(method) * 8);
774 case QCryptographicHash::Blake2b_160:
775 case QCryptographicHash::Blake2b_256:
776 case QCryptographicHash::Blake2b_384:
777 case QCryptographicHash::Blake2b_512:
778 blake2b_init(&blake2bContext, hashLengthInternal(method));
780 case QCryptographicHash::Blake2s_128:
781 case QCryptographicHash::Blake2s_160:
782 case QCryptographicHash::Blake2s_224:
783 case QCryptographicHash::Blake2s_256:
784 blake2s_init(&blake2sContext, hashLengthInternal(method));
786 case QCryptographicHash::NumAlgorithms:
793#if QT_DEPRECATED_SINCE(6
, 4
)
795
796
797
798
799
800
801void QCryptographicHash::addData(
const char *data, qsizetype length)
803 Q_ASSERT(length >= 0);
804 addData(QByteArrayView{data, length});
809
810
811
812
813
814void QCryptographicHash::addData(QByteArrayView bytes)
noexcept
821 state.addData(method, bytes);
825#ifdef USING_OPENSSL30
827void QCryptographicHashPrivate::State::addData(QCryptographicHash::Algorithm method,
828 QByteArrayView bytes)
noexcept
830 const char *data = bytes.data();
831 auto length = bytes.size();
834 case QCryptographicHash::Keccak_224:
835 case QCryptographicHash::Keccak_256:
836 case QCryptographicHash::Keccak_384:
837 case QCryptographicHash::Keccak_512:
838 sha3Update(&sha3Context,
reinterpret_cast<
const BitSequence *>(data), uint64_t(length) * 8);
840 case QCryptographicHash::Blake2b_160:
841 case QCryptographicHash::Blake2b_256:
842 case QCryptographicHash::Blake2b_384:
843 blake2b_update(&blake2bContext,
reinterpret_cast<
const uint8_t *>(data), length);
845 case QCryptographicHash::Blake2s_128:
846 case QCryptographicHash::Blake2s_160:
847 case QCryptographicHash::Blake2s_224:
848 blake2s_update(&blake2sContext,
reinterpret_cast<
const uint8_t *>(data), length);
850 case QCryptographicHash::Sha1:
851 case QCryptographicHash::Md4:
852 case QCryptographicHash::Md5:
853 case QCryptographicHash::Sha224:
854 case QCryptographicHash::Sha256:
855 case QCryptographicHash::Sha384:
856 case QCryptographicHash::Sha512:
857 case QCryptographicHash::RealSha3_224:
858 case QCryptographicHash::RealSha3_256:
859 case QCryptographicHash::RealSha3_384:
860 case QCryptographicHash::RealSha3_512:
861 case QCryptographicHash::Blake2b_512:
862 case QCryptographicHash::Blake2s_256:
863 if (!evp.initializationFailed)
864 EVP_DigestUpdate(evp.context.get(), (
const unsigned char *)data, length);
866 case QCryptographicHash::NumAlgorithms:
874 QByteArrayView bytes)
noexcept
876 const char *data = bytes.data();
877 auto length = bytes.size();
879#if QT_POINTER_SIZE == 8
883 for (
auto remaining = length; remaining; remaining -= length, data += length) {
884 length = qMin(qsizetype(std::numeric_limits<uint>::max()), remaining);
889 case QCryptographicHash::Sha1:
890 sha1Update(&sha1Context, (
const unsigned char *)data, length);
892 case QCryptographicHash::Md4:
893 md4_update(&md4Context, (
const unsigned char *)data, length);
895 case QCryptographicHash::Md5:
896 MD5Update(&md5Context, (
const unsigned char *)data, length);
898 case QCryptographicHash::Sha224:
899 SHA224Input(&
sha224Context,
reinterpret_cast<
const unsigned char *>(data), length);
901 case QCryptographicHash::Sha256:
902 SHA256Input(&
sha256Context,
reinterpret_cast<
const unsigned char *>(data), length);
904 case QCryptographicHash::Sha384:
905 SHA384Input(&
sha384Context,
reinterpret_cast<
const unsigned char *>(data), length);
907 case QCryptographicHash::Sha512:
908 SHA512Input(&
sha512Context,
reinterpret_cast<
const unsigned char *>(data), length);
910 case QCryptographicHash::RealSha3_224:
911 case QCryptographicHash::Keccak_224:
912 case QCryptographicHash::RealSha3_256:
913 case QCryptographicHash::Keccak_256:
914 case QCryptographicHash::RealSha3_384:
915 case QCryptographicHash::Keccak_384:
916 case QCryptographicHash::RealSha3_512:
917 case QCryptographicHash::Keccak_512:
920 case QCryptographicHash::Blake2b_160:
921 case QCryptographicHash::Blake2b_256:
922 case QCryptographicHash::Blake2b_384:
923 case QCryptographicHash::Blake2b_512:
924 blake2b_update(&blake2bContext,
reinterpret_cast<
const uint8_t *>(data), length);
926 case QCryptographicHash::Blake2s_128:
927 case QCryptographicHash::Blake2s_160:
928 case QCryptographicHash::Blake2s_224:
929 case QCryptographicHash::Blake2s_256:
930 blake2s_update(&blake2sContext,
reinterpret_cast<
const uint8_t *>(data), length);
932 case QCryptographicHash::NumAlgorithms:
940
941
942
943
944bool QCryptographicHash::addData(QIODevice *device)
946 return d->addData(device);
951 if (!device->isReadable())
954 if (!device->isOpen())
961 while ((length = device->read(buffer,
sizeof(buffer))) > 0)
964 return device->atEnd();
969
970
971
972
973QByteArray QCryptographicHash::result()
const
975 return resultView().toByteArray();
979
980
981
982
983
984
985
986
987
988QByteArrayView QCryptographicHash::resultView()
const noexcept
993 return d->resultView();
997
998
999
1000
1003 const auto lock = qt_scoped_lock(finalizeMutex);
1005 if (!result.isEmpty())
1011
1012
1013
1014
1015
1018 result.resizeForOverwrite(hashLengthInternal(method));
1019 state.finalizeUnchecked(method, result);
1023
1024
1025
1026
1027
1030 buffer = buffer.first(hashLengthInternal(method));
1031 state.finalizeUnchecked(method, buffer);
1032 Q_ASSERT(result.size() == 0);
1036#ifdef USING_OPENSSL30
1037void QCryptographicHashPrivate::State::finalizeUnchecked(QCryptographicHash::Algorithm method,
1038 QSpan<uchar> result)
noexcept
1041 case QCryptographicHash::Keccak_224:
1042 case QCryptographicHash::Keccak_256:
1043 case QCryptographicHash::Keccak_384:
1044 case QCryptographicHash::Keccak_512: {
1045 SHA3Context copy = sha3Context;
1046 sha3Finish(copy, result, Sha3Variant::Keccak);
1049 case QCryptographicHash::Blake2b_160:
1050 case QCryptographicHash::Blake2b_256:
1051 case QCryptographicHash::Blake2b_384: {
1052 const auto length = hashLengthInternal(method);
1053 blake2b_state copy = blake2bContext;
1054 blake2b_final(©, result.data(), length);
1057 case QCryptographicHash::Blake2s_128:
1058 case QCryptographicHash::Blake2s_160:
1059 case QCryptographicHash::Blake2s_224: {
1060 const auto length = hashLengthInternal(method);
1061 blake2s_state copy = blake2sContext;
1062 blake2s_final(©, result.data(), length);
1065 case QCryptographicHash::Sha1:
1066 case QCryptographicHash::Md4:
1067 case QCryptographicHash::Md5:
1068 case QCryptographicHash::Sha224:
1069 case QCryptographicHash::Sha256:
1070 case QCryptographicHash::Sha384:
1071 case QCryptographicHash::Sha512:
1072 case QCryptographicHash::RealSha3_224:
1073 case QCryptographicHash::RealSha3_256:
1074 case QCryptographicHash::RealSha3_384:
1075 case QCryptographicHash::RealSha3_512:
1076 case QCryptographicHash::Blake2b_512:
1077 case QCryptographicHash::Blake2s_256:
1078 evp.finalizeUnchecked(result);
1080 case QCryptographicHash::NumAlgorithms:
1085void QCryptographicHashPrivate::EVP::finalizeUnchecked(QSpan<uchar> result)
noexcept
1087 if (!initializationFailed) {
1088 EVP_MD_CTX_ptr copy = EVP_MD_CTX_ptr(EVP_MD_CTX_new());
1089 EVP_MD_CTX_copy_ex(copy.get(), context.get());
1090 Q_ASSERT(result.size() == EVP_MD_get_size(algorithm.get()));
1091 EVP_DigestFinal_ex(copy.get(), result.data(),
nullptr);
1098 QSpan<uchar> result)
noexcept
1101 case QCryptographicHash::Sha1: {
1102 Sha1State copy = sha1Context;
1103 sha1FinalizeState(©);
1104 sha1ToHash(©, result.data());
1107 case QCryptographicHash::Md4: {
1108 md4_context copy = md4Context;
1109 md4_final(©, result.data());
1112 case QCryptographicHash::Md5: {
1113 MD5Context copy = md5Context;
1114 MD5Final(©, result.data());
1117 case QCryptographicHash::Sha224: {
1119 SHA224Result(©, result.data());
1122 case QCryptographicHash::Sha256: {
1124 SHA256Result(©, result.data());
1127 case QCryptographicHash::Sha384: {
1129 SHA384Result(©, result.data());
1132 case QCryptographicHash::Sha512: {
1134 SHA512Result(©, result.data());
1137 case QCryptographicHash::RealSha3_224:
1138 case QCryptographicHash::RealSha3_256:
1139 case QCryptographicHash::RealSha3_384:
1140 case QCryptographicHash::RealSha3_512: {
1142 sha3Finish(copy, result, Sha3Variant::Sha3);
1145 case QCryptographicHash::Keccak_224:
1146 case QCryptographicHash::Keccak_256:
1147 case QCryptographicHash::Keccak_384:
1148 case QCryptographicHash::Keccak_512: {
1150 sha3Finish(copy, result, Sha3Variant::Keccak);
1153 case QCryptographicHash::Blake2b_160:
1154 case QCryptographicHash::Blake2b_256:
1155 case QCryptographicHash::Blake2b_384:
1156 case QCryptographicHash::Blake2b_512: {
1157 const auto length = hashLengthInternal(method);
1158 blake2b_state copy = blake2bContext;
1159 blake2b_final(©, result.data(), length);
1162 case QCryptographicHash::Blake2s_128:
1163 case QCryptographicHash::Blake2s_160:
1164 case QCryptographicHash::Blake2s_224:
1165 case QCryptographicHash::Blake2s_256: {
1166 const auto length = hashLengthInternal(method);
1167 blake2s_state copy = blake2sContext;
1168 blake2s_final(©, result.data(), length);
1171 case QCryptographicHash::NumAlgorithms:
1178
1179
1180
1181
1182
1183
1184
1185QByteArray QCryptographicHash::hash(QByteArrayView data, Algorithm method)
1187 QByteArray ba(hashLengthInternal(method), Qt::Uninitialized);
1188 [[maybe_unused]]
const auto r = hashInto(ba, data, method);
1189 Q_ASSERT(r.size() == ba.size());
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211QByteArrayView QCryptographicHash::hashInto(QSpan<std::byte> buffer,
1212 QSpan<
const QByteArrayView> data,
1213 Algorithm method)
noexcept
1215 if (buffer.size() < hashLengthInternal(method))
1218 Q_DECL_UNINITIALIZED
1219 QCryptographicHashPrivate hash(method);
1220 for (QByteArrayView part : data)
1222 auto span = QSpan{
reinterpret_cast<uchar *>(buffer.data()), buffer.size()};
1223 return hash.finalizeUnchecked(span);
1227
1228
1229
1230
1231int QCryptographicHash::hashLength(QCryptographicHash::Algorithm method)
1233 return hashLengthInternal(method);
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1249bool QCryptographicHash::supportsAlgorithm(QCryptographicHash::Algorithm method)
1251 return QCryptographicHashPrivate::supportsAlgorithm(method);
1254#ifdef USING_OPENSSL30
1255bool QCryptographicHashPrivate::supportsAlgorithm(QCryptographicHash::Algorithm method)
1261 case QCryptographicHash::Keccak_224:
1262 case QCryptographicHash::Keccak_256:
1263 case QCryptographicHash::Keccak_384:
1264 case QCryptographicHash::Keccak_512:
1265 case QCryptographicHash::Blake2b_160:
1266 case QCryptographicHash::Blake2b_256:
1267 case QCryptographicHash::Blake2b_384:
1268 case QCryptographicHash::Blake2s_128:
1269 case QCryptographicHash::Blake2s_160:
1270 case QCryptographicHash::Blake2s_224:
1272 case QCryptographicHash::Md4:
1273 if (OSSL_LIB_CTX *legacyLibCtx = legacyProviderContext()) {
1274 return EVP_MD_ptr{EVP_MD_fetch(legacyLibCtx, methodToName(method),
"-fips")}
1278 case QCryptographicHash::Sha1:
1279 case QCryptographicHash::Md5:
1280 case QCryptographicHash::Sha224:
1281 case QCryptographicHash::Sha256:
1282 case QCryptographicHash::Sha384:
1283 case QCryptographicHash::Sha512:
1284 case QCryptographicHash::RealSha3_224:
1285 case QCryptographicHash::RealSha3_256:
1286 case QCryptographicHash::RealSha3_384:
1287 case QCryptographicHash::RealSha3_512:
1288 case QCryptographicHash::Blake2b_512:
1289 case QCryptographicHash::Blake2s_256: {
1290 ensureDefaultProviderLoaded();
1292 const char *restriction =
"-fips";
1293 EVP_MD_ptr algorithm = EVP_MD_ptr(EVP_MD_fetch(
nullptr, methodToName(method), restriction));
1295 return algorithm !=
nullptr;
1298 case QCryptographicHash::NumAlgorithms:
1308 case QCryptographicHash::Sha1:
1309 case QCryptographicHash::Md4:
1310 case QCryptographicHash::Md5:
1311 case QCryptographicHash::Sha224:
1312 case QCryptographicHash::Sha256:
1313 case QCryptographicHash::Sha384:
1314 case QCryptographicHash::Sha512:
1315 case QCryptographicHash::RealSha3_224:
1316 case QCryptographicHash::Keccak_224:
1317 case QCryptographicHash::RealSha3_256:
1318 case QCryptographicHash::Keccak_256:
1319 case QCryptographicHash::RealSha3_384:
1320 case QCryptographicHash::Keccak_384:
1321 case QCryptographicHash::RealSha3_512:
1322 case QCryptographicHash::Keccak_512:
1323 case QCryptographicHash::Blake2b_160:
1324 case QCryptographicHash::Blake2b_256:
1325 case QCryptographicHash::Blake2b_384:
1326 case QCryptographicHash::Blake2b_512:
1327 case QCryptographicHash::Blake2s_128:
1328 case QCryptographicHash::Blake2s_160:
1329 case QCryptographicHash::Blake2s_224:
1330 case QCryptographicHash::Blake2s_256:
1332 case QCryptographicHash::NumAlgorithms: ;
1341 case QCryptographicHash::Sha1:
1342 return SHA1_Message_Block_Size;
1343 case QCryptographicHash::Md4:
1345 case QCryptographicHash::Md5:
1347 case QCryptographicHash::Sha224:
1348 return SHA224_Message_Block_Size;
1349 case QCryptographicHash::Sha256:
1350 return SHA256_Message_Block_Size;
1351 case QCryptographicHash::Sha384:
1352 return SHA384_Message_Block_Size;
1353 case QCryptographicHash::Sha512:
1354 return SHA512_Message_Block_Size;
1355 case QCryptographicHash::RealSha3_224:
1356 case QCryptographicHash::Keccak_224:
1358 case QCryptographicHash::RealSha3_256:
1359 case QCryptographicHash::Keccak_256:
1361 case QCryptographicHash::RealSha3_384:
1362 case QCryptographicHash::Keccak_384:
1364 case QCryptographicHash::RealSha3_512:
1365 case QCryptographicHash::Keccak_512:
1367 case QCryptographicHash::Blake2b_160:
1368 case QCryptographicHash::Blake2b_256:
1369 case QCryptographicHash::Blake2b_384:
1370 case QCryptographicHash::Blake2b_512:
1371 return BLAKE2B_BLOCKBYTES;
1372 case QCryptographicHash::Blake2s_128:
1373 case QCryptographicHash::Blake2s_160:
1374 case QCryptographicHash::Blake2s_224:
1375 case QCryptographicHash::Blake2s_256:
1376 return BLAKE2S_BLOCKBYTES;
1377 case QCryptographicHash::NumAlgorithms:
1378#if !defined(Q_CC_GNU_ONLY) || Q_CC_GNU >= 900
1390 using A = QCryptographicHash::Algorithm;
1391 for (
int i = 0; i < A::NumAlgorithms ; ++i)
1392 result =
std::max(result, qt_hash_block_size(A(i)));
1399 int result = INT_MAX;
1400 using A = QCryptographicHash::Algorithm;
1401 for (
int i = 0; i < A::NumAlgorithms ; ++i)
1402 result =
std::min(result, qt_hash_block_size(A(i)));
1410 using A = QCryptographicHash::Algorithm;
1411 for (
int i = 0; i < A::NumAlgorithms ; ++i)
1412 result =
std::gcd(result, qt_hash_block_size(A(i)));
1416using HashBlock = QSmallByteArray<maxHashBlockSize()>;
1425 Q_DECL_UNINITIALIZED
1427 result.resizeForOverwrite(block.size());
1428 for (qsizetype i = 0; i < block.size(); ++i)
1429 result[i] = block[i] ^ val;
1455
1456
1457
1458
1459
1460
1461
1462
1465 const int blockSize = qt_hash_block_size(messageHash.method);
1467 if (newKey.size() > blockSize) {
1468 messageHash.addData(newKey);
1469 messageHash.finalizeUnchecked();
1471 using A = QCryptographicHash::Algorithm;
1472 for (
int i = 0; i < A::NumAlgorithms; ++i) {
1473 if (hashLengthInternal(A(i)) > qt_hash_block_size(A(i)))
1477 }(),
"this code assumes that a hash's result always fits into that hash's block size");
1478 key = messageHash.result;
1479 messageHash.reset();
1484 if (key.size() < blockSize)
1485 key.resize(blockSize,
'\0');
1491
1492
1493
1494
1495
1496
1497
1500 messageHash.addData(xored(key, 0x36));
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556QMessageAuthenticationCode::QMessageAuthenticationCode(QCryptographicHash::Algorithm method,
1558 : d(
new QMessageAuthenticationCodePrivate(method))
1564
1565
1566QMessageAuthenticationCode::~QMessageAuthenticationCode()
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1596
1597
1598
1599
1602
1603
1604void QMessageAuthenticationCode::reset()
noexcept
1606 d->messageHash.reset();
1607 d->initMessageHash();
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642void QMessageAuthenticationCode::setKey(QByteArrayView key)
noexcept
1644 d->messageHash.reset();
1649
1650
1651
1652void QMessageAuthenticationCode::addData(
const char *data, qsizetype length)
1654 d->messageHash.addData({data, length});
1658
1659
1660
1661
1662
1663
1664void QMessageAuthenticationCode::addData(QByteArrayView data)
noexcept
1666 d->messageHash.addData(data);
1670
1671
1672
1673
1674
1675bool QMessageAuthenticationCode::addData(QIODevice *device)
1677 return d->messageHash.addData(device);
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690QByteArrayView QMessageAuthenticationCode::resultView()
const noexcept
1693 return d->messageHash.resultView();
1697
1698
1699
1700
1701QByteArray QMessageAuthenticationCode::result()
const
1703 return resultView().toByteArray();
1708 const auto lock = qt_scoped_lock(messageHash.finalizeMutex);
1709 if (!messageHash.result.isEmpty())
1716 messageHash.finalizeUnchecked();
1717 const HashResult hashedMessage = messageHash.result;
1719 messageHash.reset();
1720 messageHash.addData(xored(key, 0x5c));
1721 messageHash.addData(hashedMessage);
1722 messageHash.finalizeUnchecked();
1726
1727
1728
1729
1730
1731
1732
1733QByteArray QMessageAuthenticationCode::hash(QByteArrayView message, QByteArrayView key,
1734 QCryptographicHash::Algorithm method)
1736 QByteArray ba(hashLengthInternal(method), Qt::Uninitialized);
1737 [[maybe_unused]]
const auto r = hashInto(ba, message, key, method);
1738 Q_ASSERT(r.size() == ba.size());
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760QByteArrayView QMessageAuthenticationCode::hashInto(QSpan<std::byte> buffer,
1761 QSpan<
const QByteArrayView> messageParts,
1763 QCryptographicHash::Algorithm method)
noexcept
1765 Q_DECL_UNINITIALIZED
1766 QMessageAuthenticationCodePrivate mac(method);
1768 for (QByteArrayView part : messageParts)
1769 mac.messageHash.addData(part);
1770 mac.finalizeUnchecked();
1771 auto result = mac.messageHash.resultView();
1772 if (buffer.size() < result.size())
1775 memcpy(buffer.data(), result.data(), result.size());
1776 return buffer.first(result.size());
1781#ifndef QT_NO_QOBJECT
1782#include "moc_qcryptographichash.cpp"
QBasicMutex finalizeMutex
void addData(QByteArrayView bytes) noexcept
~QCryptographicHashPrivate()
QCryptographicHashPrivate(QCryptographicHash::Algorithm method) noexcept
void finalizeUnchecked() noexcept
QByteArrayView resultView() const noexcept
static bool supportsAlgorithm(QCryptographicHash::Algorithm method)
bool addData(QIODevice *dev)
QSpan< uchar > finalizeUnchecked(QSpan< uchar > buffer) noexcept
QMessageAuthenticationCodePrivate(QCryptographicHash::Algorithm m) noexcept
void initMessageHash() noexcept
void setKey(QByteArrayView k) noexcept
QCryptographicHashPrivate messageHash
void finalizeUnchecked() noexcept
Combined button and popup list for selecting options.
constexpr int maxHashBlockSize()
QT_WARNING_PUSH QT_WARNING_POP static QT_BEGIN_NAMESPACE constexpr int hashLengthInternal(QCryptographicHash::Algorithm method) noexcept
static constexpr int qt_hash_block_size(QCryptographicHash::Algorithm method)
static HashBlock xored(const HashBlock &block, quint8 val) noexcept
static constexpr int maxHashLength()
constexpr int minHashBlockSize()
constexpr int gcdHashBlockSize()
unsigned long long DataLength
unsigned char BitSequence
static void sha3Finish(SHA3Context &ctx, QSpan< uchar > result, Sha3Variant sha3Variant)
blake2b_state blake2bContext
SHA384Context sha384Context
SHA224Context sha224Context
void addData(QCryptographicHash::Algorithm method, QByteArrayView data) noexcept
SHA512Context sha512Context
SHA256Context sha256Context
void finalizeUnchecked(QCryptographicHash::Algorithm method, QSpan< uchar > buffer) noexcept
void destroy(QCryptographicHash::Algorithm method)
blake2s_state blake2sContext
State(QCryptographicHash::Algorithm method)
void reset(QCryptographicHash::Algorithm method) noexcept