Fix overflow in SHA-3/Keccak
state->rate is always larger than or equal to state->bitsInQueue; when bitsInQueue == rate the queue is consumed and bitsInQueue is set to 0 again. Done-with: Marc Mutz <marc.mutz@qt.io> Pick-to: 6.5.0 6.5 6.4.3 6.4 6.2 5.15 Change-Id: I56d268a19fb3cd542cc027edc962253f09d97a14 Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
4f02973e2f
commit
fa4b7495b7
5
src/3rdparty/sha3/KeccakSponge.c
vendored
5
src/3rdparty/sha3/KeccakSponge.c
vendored
@ -170,9 +170,10 @@ static int Absorb(spongeState *state, const unsigned char *data, unsigned long l
|
|||||||
i += wholeBlocks*state->rate;
|
i += wholeBlocks*state->rate;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
partialBlock = (unsigned int)(databitlen - i);
|
if (databitlen-i > state->rate - state->bitsInQueue)
|
||||||
if (partialBlock+state->bitsInQueue > state->rate)
|
|
||||||
partialBlock = state->rate-state->bitsInQueue;
|
partialBlock = state->rate-state->bitsInQueue;
|
||||||
|
else
|
||||||
|
partialBlock = (unsigned int)(databitlen - i);
|
||||||
partialByte = partialBlock % 8;
|
partialByte = partialBlock % 8;
|
||||||
partialBlock -= partialByte;
|
partialBlock -= partialByte;
|
||||||
memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8);
|
memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8);
|
||||||
|
31
src/3rdparty/sha3/overflow.patch
vendored
Normal file
31
src/3rdparty/sha3/overflow.patch
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
From a60180d3f8ffac268f02d2d4b0b4fbf1bff50f11 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= <marten.nordheim@qt.io>
|
||||||
|
Date: Wed, 8 Mar 2023 11:10:49 +0100
|
||||||
|
Subject: [PATCH] Fix overflow in SHA-3/Keccak
|
||||||
|
|
||||||
|
Pick-to: 6.5.0 6.5 6.4.3 6.4 6.2 5.15
|
||||||
|
Change-Id: I56d268a19fb3cd542cc027edc962253f09d97a14
|
||||||
|
---
|
||||||
|
src/3rdparty/sha3/KeccakSponge.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/3rdparty/sha3/KeccakSponge.c b/src/3rdparty/sha3/KeccakSponge.c
|
||||||
|
index 6f3da95dbb..337c10ccaf 100644
|
||||||
|
--- a/src/3rdparty/sha3/KeccakSponge.c
|
||||||
|
+++ b/src/3rdparty/sha3/KeccakSponge.c
|
||||||
|
@@ -170,9 +170,10 @@ static int Absorb(spongeState *state, const unsigned char *data, unsigned long l
|
||||||
|
i += wholeBlocks*state->rate;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
- partialBlock = (unsigned int)(databitlen - i);
|
||||||
|
- if (partialBlock+state->bitsInQueue > state->rate)
|
||||||
|
+ if (databitlen-i > state->rate - state->bitsInQueue)
|
||||||
|
partialBlock = state->rate-state->bitsInQueue;
|
||||||
|
+ else
|
||||||
|
+ partialBlock = (unsigned int)(databitlen - i);
|
||||||
|
partialByte = partialBlock % 8;
|
||||||
|
partialBlock -= partialByte;
|
||||||
|
memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8);
|
||||||
|
--
|
||||||
|
2.39.2.vfs.0.0
|
||||||
|
|
1
src/3rdparty/sha3/qt_attribution.json
vendored
1
src/3rdparty/sha3/qt_attribution.json
vendored
@ -21,6 +21,7 @@
|
|||||||
"QtUsage": "Used in Qt Core (QCryptographicHash).",
|
"QtUsage": "Used in Qt Core (QCryptographicHash).",
|
||||||
"Files": "https://keccak.team/obsolete/KeccakReferenceAndOptimized-3.2.zip - but it's obsolete",
|
"Files": "https://keccak.team/obsolete/KeccakReferenceAndOptimized-3.2.zip - but it's obsolete",
|
||||||
"Files": "KeccakF-1600-32-rvk.macros KeccakF-1600-32.macros KeccakF-1600-64.macros KeccakF-1600-interface.h KeccakF-1600-opt32.c KeccakF-1600-opt64.c KeccakF-1600-unrolling.macros KeccakNISTInterface.c KeccakNISTInterface.h KeccakSponge.c KeccakSponge.h",
|
"Files": "KeccakF-1600-32-rvk.macros KeccakF-1600-32.macros KeccakF-1600-64.macros KeccakF-1600-interface.h KeccakF-1600-opt32.c KeccakF-1600-opt64.c KeccakF-1600-unrolling.macros KeccakNISTInterface.c KeccakNISTInterface.h KeccakSponge.c KeccakSponge.h",
|
||||||
|
"Files": "With overflow.patch applied",
|
||||||
|
|
||||||
"Description": "SHA-3, originally known as Keccak, is a cryptographic hash function.",
|
"Description": "SHA-3, originally known as Keccak, is a cryptographic hash function.",
|
||||||
"Version": "3.2",
|
"Version": "3.2",
|
||||||
|
@ -36,6 +36,7 @@ private slots:
|
|||||||
// keep last
|
// keep last
|
||||||
void moreThan4GiBOfData_data();
|
void moreThan4GiBOfData_data();
|
||||||
void moreThan4GiBOfData();
|
void moreThan4GiBOfData();
|
||||||
|
void keccakBufferOverflow();
|
||||||
private:
|
private:
|
||||||
void ensureLargeData();
|
void ensureLargeData();
|
||||||
std::vector<char> large;
|
std::vector<char> large;
|
||||||
@ -534,5 +535,33 @@ void tst_QCryptographicHash::moreThan4GiBOfData()
|
|||||||
QCOMPARE(single, chunked);
|
QCOMPARE(single, chunked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QCryptographicHash::keccakBufferOverflow()
|
||||||
|
{
|
||||||
|
#if QT_POINTER_SIZE == 4
|
||||||
|
QSKIP("This is a 64-bit-only test");
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (ensureLargeData(); large.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
|
const auto sg = qScopeGuard([&] {
|
||||||
|
qDebug() << "test finished in" << timer.restart() << "ms";
|
||||||
|
});
|
||||||
|
|
||||||
|
constexpr qsizetype magic = INT_MAX/4;
|
||||||
|
QCOMPARE_GE(large.size(), size_t(magic + 1));
|
||||||
|
|
||||||
|
QCryptographicHash hash(QCryptographicHash::Algorithm::Keccak_224);
|
||||||
|
const auto first = QByteArrayView{large}.first(1);
|
||||||
|
const auto second = QByteArrayView{large}.sliced(1, magic);
|
||||||
|
hash.addData(first);
|
||||||
|
hash.addData(second);
|
||||||
|
(void)hash.resultView();
|
||||||
|
QVERIFY(true); // didn't crash
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QCryptographicHash)
|
QTEST_MAIN(tst_QCryptographicHash)
|
||||||
#include "tst_qcryptographichash.moc"
|
#include "tst_qcryptographichash.moc"
|
||||||
|
Loading…
Reference in New Issue
Block a user