crypto: handle unaligned Groestl input

This commit is contained in:
Samy
2026-08-31 00:30:46 +02:00
parent 78fb311ebb
commit 722de8ed3d
2 changed files with 28 additions and 4 deletions
+7 -4
View File
@@ -9,6 +9,7 @@
*/
#include <stddef.h>
#include <string.h>
#include "groestl.h"
#include "groestl_tables.h"
@@ -124,7 +125,7 @@ static void RND512Q(uint8_t *x, uint32_t *y, uint32_t r) {
}
/* compute compression function (short variants) */
static void F512(uint32_t *h, const uint32_t *m) {
static void F512(uint32_t *h, const uint8_t *m) {
int i;
uint32_t Ptmp[2*COLS512];
uint32_t Qtmp[2*COLS512];
@@ -132,8 +133,10 @@ static void F512(uint32_t *h, const uint32_t *m) {
uint32_t z[2*COLS512];
for (i = 0; i < 2*COLS512; i++) {
z[i] = m[i];
Ptmp[i] = h[i]^m[i];
uint32_t word;
memcpy(&word, m + i*sizeof(word), sizeof(word));
z[i] = word;
Ptmp[i] = h[i]^word;
}
/* compute Q(m) */
@@ -175,7 +178,7 @@ static void Transform(hashState *ctx,
/* digest message, one block at a time */
for (; msglen >= SIZE512;
msglen -= SIZE512, input += SIZE512) {
F512(ctx->chaining,(uint32_t*)input);
F512(ctx->chaining, input);
/* increment block counter */
ctx->block_counter1++;
+21
View File
@@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdint>
#include <cstring>
#include <gtest/gtest.h>
#include <memory>
#include <sstream>
@@ -102,6 +103,26 @@ TEST(Crypto, null_keys)
ASSERT_EQ(memcmp(crypto::null_pkey.data, zero, 32), 0);
}
TEST(Crypto, groestl_unaligned_input)
{
constexpr std::size_t input_size = 128;
alignas(std::uint32_t) std::uint8_t aligned[input_size];
alignas(std::uint32_t) std::uint8_t input[input_size + alignof(std::uint32_t)];
char expected[crypto::HASH_SIZE];
char actual[crypto::HASH_SIZE];
for (std::size_t i = 0; i < input_size; ++i)
aligned[i] = static_cast<std::uint8_t>(i);
crypto::hash_extra_groestl(aligned, input_size, expected);
for (std::size_t offset = 0; offset < alignof(std::uint32_t); ++offset)
{
std::memcpy(input + offset, aligned, input_size);
crypto::hash_extra_groestl(input + offset, input_size, actual);
EXPECT_EQ(0, std::memcmp(expected, actual, sizeof(expected)));
}
}
TEST(Crypto, verify_32)
{
// all bytes are treated the same, so we can brute force just one byte