12#include <private/qlocking_p.h>
18#include "../../3rdparty/sha1/sha1.cpp"
20#if defined(QT_BOOTSTRAPPED) && !defined(QT_CRYPTOGRAPHICHASH_ONLY_SHA1)
21# error "Are you sure you need the other hashing algorithms besides SHA-1?"
25#include "../../3rdparty/rfc6234/sha.h"
27#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
28#if !QT_CONFIG(openssl_hash)
30#include "../../3rdparty/md5/md5.h"
31#include "../../3rdparty/md5/md5.cpp"
32#include "../../3rdparty/md4/md4.h"
33#include "../../3rdparty/md4/md4.cpp"
44#include "../../3rdparty/sha3/KeccakSponge.c"
47#include "../../3rdparty/sha3/KeccakNISTInterface.c"
57#if Q_PROCESSOR_WORDSIZE == 8
59#include "../../3rdparty/sha3/KeccakF-1600-opt64.c"
67#include "../../3rdparty/sha3/KeccakF-1600-opt32.c"
75#if !QT_CONFIG(openssl_hash)
92#include "../../3rdparty/rfc6234/sha224-256.c"
95#include "../../3rdparty/rfc6234/sha384-512.c"
109#include "qtcore-config_p.h"
111#if QT_CONFIG(system_libb2)
114#include "../../3rdparty/blake2/src/blake2b-ref.c"
115#include "../../3rdparty/blake2/src/blake2s-ref.c"
119#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(openssl_hash)
120#define USING_OPENSSL30
121#include <openssl/evp.h>
122#include <openssl/provider.h>
130 std::array<quint8, N> m_data;
131 static_assert(N <= std::numeric_limits<std::uint8_t>::max());
136 template <std::
size_t M, std::enable_if_t<M < N,
bool> = true>
137 constexpr QSmallByteArray(const QSmallByteArray<M> &other) noexcept
141 template <std::
size_t M, std::enable_if_t<M < N,
bool> = true>
142 constexpr QSmallByteArray &operator=(const QSmallByteArray<M> &other) noexcept
148 template <
typename Container>
149 constexpr void assign(
const Container &
c)
151 const size_t otherSize = size_t(std::size(
c));
153 memcpy(
data(), std::data(
c), otherSize);
154 m_size =
quint8(otherSize);
170 constexpr bool isEmpty() const noexcept {
return size() == 0; }
171 constexpr void clear() noexcept { m_size = 0; }
172 constexpr void resizeForOverwrite(
qsizetype s)
176 m_size = std::uint8_t(
s);
180 const auto oldSize =
size();
181 resizeForOverwrite(
s);
183 memset(
data() + oldSize,
v,
size() - oldSize);
188 constexpr auto begin() noexcept {
return data(); }
189 constexpr auto begin() const noexcept {
return data(); }
190 constexpr auto cbegin() const noexcept {
return begin(); }
191 constexpr auto end() noexcept {
return data() +
size(); }
192 constexpr auto end() const noexcept {
return data() +
size(); }
193 constexpr auto cend() const noexcept {
return end(); }
199#define CASE(Enum, Size) \
200 case QCryptographicHash:: Enum : \
204#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
207 CASE(Sha224, SHA224HashSize);
208 CASE(Sha256, SHA256HashSize);
209 CASE(Sha384, SHA384HashSize);
210 CASE(Sha512, SHA512HashSize);
211 CASE(Blake2s_128, 128 / 8);
245 for (
int i = 0;
i < A::NumAlgorithms; ++
i)
252#ifdef USING_OPENSSL30
256#define CASE(Enum, Name) \
257 case QCryptographicHash:: Enum : \
263 CASE(Sha224,
"SHA224");
264 CASE(Sha256,
"SHA256");
265 CASE(Sha384,
"SHA384");
266 CASE(Sha512,
"SHA512");
267 CASE(RealSha3_224,
"SHA3-224");
268 CASE(RealSha3_256,
"SHA3-256");
269 CASE(RealSha3_384,
"SHA3-384");
270 CASE(RealSha3_512,
"SHA3-512");
271 CASE(Blake2b_512,
"BLAKE2B512");
272 CASE(Blake2s_256,
"BLAKE2S256");
274 default:
return nullptr;
307 void reset() noexcept;
310 void finalize() noexcept;
313 void finalizeUnchecked() noexcept;
318#ifdef USING_OPENSSL30
319 struct EVP_MD_CTX_deleter {
320 void operator()(EVP_MD_CTX *
ctx)
const noexcept {
321 EVP_MD_CTX_free(
ctx);
324 struct EVP_MD_deleter {
325 void operator()(EVP_MD *md)
const noexcept {
329 struct OSSL_PROVIDER_deleter {
330 void operator()(OSSL_PROVIDER *provider)
const noexcept {
331 OSSL_PROVIDER_unload(provider);
335 using EVP_MD_CTX_ptr = std::unique_ptr<EVP_MD_CTX, EVP_MD_CTX_deleter>;
336 using EVP_MD_ptr = std::unique_ptr<EVP_MD, EVP_MD_deleter>;
337 using OSSL_PROVIDER_ptr = std::unique_ptr<OSSL_PROVIDER, OSSL_PROVIDER_deleter>;
339 EVP_MD_ptr algorithm;
341 OSSL_PROVIDER_ptr defaultProvider;
342 OSSL_PROVIDER_ptr legacyProvider;
343 bool initializationFailed;
346 void reset() noexcept;
354#ifdef USING_OPENSSL30
363#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
364#ifdef USING_OPENSSL30
389#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
413 static const unsigned char sha3FinalSuffix = 0x80;
415 result.resizeForOverwrite(bitCount / 8);
419 switch (sha3Variant) {
554#ifdef USING_OPENSSL30
596 : initializationFailed{true}
603 legacyProvider = OSSL_PROVIDER_ptr(OSSL_PROVIDER_load(
nullptr,
"legacy"));
609 defaultProvider = OSSL_PROVIDER_ptr(OSSL_PROVIDER_load(
nullptr,
"default"));
610 if (!defaultProvider)
613 context = EVP_MD_CTX_ptr(EVP_MD_CTX_new());
624 algorithm = EVP_MD_ptr(EVP_MD_fetch(
nullptr, methodToName(
method),
"-fips"));
629 initializationFailed = !EVP_DigestInit_ex(
context.get(),
algorithm.get(),
nullptr);
640#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
642 Q_ASSERT_X(
false,
"QCryptographicHash",
"Method not compiled in");
695 static_assert(std::is_trivially_destructible_v<State>);
705#ifdef USING_OPENSSL30
727void QCryptographicHashPrivate::EVP::reset() noexcept
729 if (!initializationFailed) {
733 EVP_MD_CTX_reset(
context.get());
734 initializationFailed = !EVP_DigestInit_ex(
context.get(), algorithm.get(),
nullptr);
745 sha1InitState(&sha1Context);
747#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
749 Q_ASSERT_X(
false,
"QCryptographicHash",
"Method not compiled in");
754 md4_init(&md4Context);
757 MD5Init(&md5Context);
760 SHA224Reset(&sha224Context);
763 SHA256Reset(&sha256Context);
766 SHA384Reset(&sha384Context);
769 SHA512Reset(&sha512Context);
801#if QT_DEPRECATED_SINCE(6, 4)
833#ifdef USING_OPENSSL30
838 const char *
data = bytes.data();
839 auto length = bytes.size();
850 blake2b_update(&blake2bContext,
reinterpret_cast<const uint8_t *
>(
data),
length);
854 blake2s_update(&blake2sContext,
reinterpret_cast<const uint8_t *
>(
data),
length);
855 }
else if (!evp.initializationFailed) {
856 EVP_DigestUpdate(evp.context.get(), (
const unsigned char *)
data,
length);
866 const char *
data = bytes.data();
867 auto length = bytes.size();
869#if QT_POINTER_SIZE == 8
880 sha1Update(&sha1Context, (
const unsigned char *)
data,
length);
882#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
884 Q_ASSERT_X(
false,
"QCryptographicHash",
"Method not compiled in");
889 md4_update(&md4Context, (
const unsigned char *)
data,
length);
892 MD5Update(&md5Context, (
const unsigned char *)
data,
length);
895 SHA224Input(&sha224Context,
reinterpret_cast<const unsigned char *
>(
data),
length);
898 SHA256Input(&sha256Context,
reinterpret_cast<const unsigned char *
>(
data),
length);
901 SHA384Input(&sha384Context,
reinterpret_cast<const unsigned char *
>(
data),
length);
904 SHA512Input(&sha512Context,
reinterpret_cast<const unsigned char *
>(
data),
length);
920 blake2b_update(&blake2bContext,
reinterpret_cast<const uint8_t *
>(
data),
length);
926 blake2s_update(&blake2sContext,
reinterpret_cast<const uint8_t *
>(
data),
length);
948 if (!
device->isReadable())
989 return d->resultView();
1017#ifdef USING_OPENSSL30
1030 blake2b_state
copy = blake2bContext;
1037 blake2s_state
copy = blake2sContext;
1041 evp.finalizeUnchecked(
result);
1045void QCryptographicHashPrivate::EVP::finalizeUnchecked(
HashResult &
result)
noexcept
1047 if (!initializationFailed) {
1048 EVP_MD_CTX_ptr
copy = EVP_MD_CTX_ptr(EVP_MD_CTX_new());
1050 result.resizeForOverwrite(EVP_MD_get_size(algorithm.get()));
1051 EVP_DigestFinal_ex(
copy.get(),
result.data(),
nullptr);
1062 Sha1State
copy = sha1Context;
1063 result.resizeForOverwrite(20);
1064 sha1FinalizeState(&
copy);
1068#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
1070 Q_ASSERT_X(
false,
"QCryptographicHash",
"Method not compiled in");
1075 md4_context
copy = md4Context;
1076 result.resizeForOverwrite(MD4_RESULTLEN);
1081 MD5Context
copy = md5Context;
1082 result.resizeForOverwrite(16);
1087 SHA224Context
copy = sha224Context;
1088 result.resizeForOverwrite(SHA224HashSize);
1093 SHA256Context
copy = sha256Context;
1094 result.resizeForOverwrite(SHA256HashSize);
1099 SHA384Context
copy = sha384Context;
1100 result.resizeForOverwrite(SHA384HashSize);
1105 SHA512Context
copy = sha512Context;
1106 result.resizeForOverwrite(SHA512HashSize);
1129 blake2b_state
copy = blake2bContext;
1139 blake2s_state
copy = blake2sContext;
1161 hash.finalizeUnchecked();
1162 return hash.resultView().toByteArray();
1195#ifdef USING_OPENSSL30
1199 if (useNonOpenSSLFallback(
method))
1202 auto legacyProvider = OSSL_PROVIDER_ptr(OSSL_PROVIDER_load(
nullptr,
"legacy"));
1203 auto defaultProvider = OSSL_PROVIDER_ptr(OSSL_PROVIDER_load(
nullptr,
"default"));
1205 const char *restriction =
"-fips";
1206 EVP_MD_ptr algorithm = EVP_MD_ptr(EVP_MD_fetch(
nullptr, methodToName(
method), restriction));
1208 return algorithm !=
nullptr;
1212#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
1247 return SHA1_Message_Block_Size;
1248#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
1254 return SHA224_Message_Block_Size;
1256 return SHA256_Message_Block_Size;
1258 return SHA384_Message_Block_Size;
1260 return SHA512_Message_Block_Size;
1277 return BLAKE2B_BLOCKBYTES;
1282 return BLAKE2S_BLOCKBYTES;
1285#if !defined(Q_CC_GNU_ONLY) || Q_CC_GNU >= 900
1298 for (
int i = 0;
i < A::NumAlgorithms ; ++
i)
1308 for (
int i = 0;
i < A::NumAlgorithms ; ++
i)
1318 for (
int i = 0;
i < A::NumAlgorithms ; ++
i)
1332 result.resizeForOverwrite(block.size());
1350 void initMessageHash() noexcept;
1377 for (
int i = 0;
i < A::NumAlgorithms; ++
i) {
1382 }(),
"this code assumes that a hash's result always fits into that hash's block size");
1384 messageHash.
reset();
1552 d->messageHash.reset();
1574 d->messageHash.addData(
data);
1644 mac.messageHash.addData(
message);
1645 mac.finalizeUnchecked();
1646 return mac.messageHash.resultView().toByteArray();
1651#ifndef QT_NO_QOBJECT
1652#include "moc_qcryptographichash.cpp"
IOBluetoothDevice * device
QByteArray toByteArray() const
const QCryptographicHash::Algorithm method
QBasicMutex finalizeMutex
void addData(QByteArrayView bytes) noexcept
~QCryptographicHashPrivate()
QCryptographicHashPrivate(QCryptographicHash::Algorithm method) noexcept
void finalizeUnchecked() noexcept
union QCryptographicHashPrivate::State state
QByteArrayView resultView() const noexcept
static bool supportsAlgorithm(QCryptographicHash::Algorithm method)
~QCryptographicHash()
Destroys the object.
static int hashLength(Algorithm method)
Returns the size of the output of the selected hash method in bytes.
QByteArrayView resultView() const noexcept
static QByteArray hash(QByteArrayView data, Algorithm method)
Returns the hash of data using method.
static bool supportsAlgorithm(Algorithm method)
Returns whether the selected algorithm method is supported and if result() will return a value when t...
void addData(QByteArrayView data) noexcept
Adds the characters in bytes to the cryptographic hash.
QByteArray result() const
Returns the final hash value.
QCryptographicHash(Algorithm method)
Constructs an object that can be used to create a cryptographic hash from data using method.
void reset() noexcept
Resets the object.
Algorithm algorithm() const noexcept
Returns the algorithm used to generate the cryptographic hash.
\inmodule QtCore \reentrant
void initMessageHash() noexcept
QMessageAuthenticationCodePrivate(QCryptographicHash::Algorithm m)
void setKey(QByteArrayView k) noexcept
QCryptographicHashPrivate messageHash
void finalizeUnchecked() noexcept
~QMessageAuthenticationCode()
Destroys the object.
void setKey(QByteArrayView key) noexcept
Sets secret key.
QByteArrayView resultView() const noexcept
void addData(const char *data, qsizetype length)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray result() const
Returns the final authentication code.
void reset() noexcept
Resets message data.
static QByteArray hash(QByteArrayView message, QByteArrayView key, QCryptographicHash::Algorithm method)
Returns the authentication code for the message message using the key key and the method method.
QMessageAuthenticationCode(QCryptographicHash::Algorithm method, QByteArrayView key={})
QSmallByteArray()=default
QHash< int, QWidget * > hash
[35multi]
const PluginKeyMapConstIterator cend
Combined button and popup list for selecting options.
static jboolean copy(JNIEnv *, jobject)
static int SHA224_256AddLength(SHA256Context *context, unsigned int length)
static constexpr int hashLengthInternal(QCryptographicHash::Algorithm method) noexcept
constexpr int maxHashBlockSize()
static int SHA384_512AddLength(SHA512Context *context, unsigned int length)
HashReturn SHA3Update(hashState *state, const BitSequence *data, DataLength databitlen)
static Q_CONSTINIT SHA3Update *const sha3Update
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()
HashReturn SHA3Init(hashState *state, int hashbitlen)
static Q_CONSTINIT SHA3Init *const sha3Init
unsigned long long DataLength
HashReturn SHA3Final(hashState *state, BitSequence *hashval)
unsigned char BitSequence
static Q_CONSTINIT SHA3Final *const sha3Final
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
constexpr const T & qMin(const T &a, const T &b)
GLsizei const GLfloat * v
[13]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint GLsizei const GLchar * message
#define Q_ASSERT_X(cond, x, msg)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
blake2b_state blake2bContext
SHA384Context sha384Context
SHA224Context sha224Context
void addData(QCryptographicHash::Algorithm method, QByteArrayView data) noexcept
void sha3Finish(HashResult &result, int bitCount, Sha3Variant sha3Variant)
SHA512Context sha512Context
void finalizeUnchecked(QCryptographicHash::Algorithm method, HashResult &result) noexcept
SHA256Context sha256Context
void destroy(QCryptographicHash::Algorithm method)
blake2s_state blake2sContext
State(QCryptographicHash::Algorithm method)
void reset(QCryptographicHash::Algorithm method) noexcept