sha3: make post-final misuse safe and deterministic

This commit is contained in:
Frank Denis
2026-04-08 00:16:01 +02:00
parent fd52fd61a2
commit f54f20abbf
5 changed files with 183 additions and 17 deletions
+73
View File
@@ -2,6 +2,8 @@
#define TEST_NAME "hash_sha3256"
#include "cmptest.h"
#define TEST_SHA3_256_BYTES 32U
int
main(void)
{
@@ -125,6 +127,77 @@ main(void)
printf("Rate-1 boundary test passed\n");
}
{
static const unsigned char resumed_msg[] = { 0x78, 0x79 };
static const unsigned char resumed_msg_other[] = { 0x78, 0x7a };
unsigned char resumed_out1[TEST_SHA3_256_BYTES];
unsigned char resumed_out2[TEST_SHA3_256_BYTES];
unsigned char resumed_out3[TEST_SHA3_256_BYTES];
crypto_hash_sha3256_state state2;
crypto_hash_sha3256_state state3;
int ret;
crypto_hash_sha3256_init(&state);
crypto_hash_sha3256_init(&state2);
crypto_hash_sha3256_init(&state3);
crypto_hash_sha3256_update(&state, msg_abc, 3);
crypto_hash_sha3256_update(&state2, msg_abc, 3);
crypto_hash_sha3256_update(&state3, msg_abc, 3);
crypto_hash_sha3256_final(&state, out);
crypto_hash_sha3256_final(&state2, resumed_out2);
crypto_hash_sha3256_final(&state3, resumed_out3);
assert(memcmp(out, out_abc, 32) == 0);
assert(memcmp(resumed_out2, out_abc, 32) == 0);
assert(memcmp(resumed_out3, out_abc, 32) == 0);
ret = crypto_hash_sha3256_update(&state, resumed_msg, sizeof resumed_msg);
assert(ret == -1);
ret = crypto_hash_sha3256_update(&state2, resumed_msg, sizeof resumed_msg);
assert(ret == -1);
ret = crypto_hash_sha3256_update(&state3, resumed_msg_other, sizeof resumed_msg_other);
assert(ret == -1);
ret = crypto_hash_sha3256_final(&state, resumed_out1);
assert(ret == 0);
ret = crypto_hash_sha3256_final(&state2, resumed_out2);
assert(ret == 0);
ret = crypto_hash_sha3256_final(&state3, resumed_out3);
assert(ret == 0);
assert(memcmp(resumed_out1, resumed_out2, TEST_SHA3_256_BYTES) == 0);
assert(memcmp(resumed_out1, resumed_out3, TEST_SHA3_256_BYTES) != 0);
printf("Update-after-final recovery test passed\n");
}
{
unsigned char repeated_out1[TEST_SHA3_256_BYTES];
unsigned char repeated_out2[TEST_SHA3_256_BYTES];
crypto_hash_sha3256_state state2;
int ret;
memset(repeated_out1, 0xAA, sizeof repeated_out1);
memset(repeated_out2, 0xAA, sizeof repeated_out2);
crypto_hash_sha3256_init(&state);
crypto_hash_sha3256_init(&state2);
crypto_hash_sha3256_update(&state, msg_abc, 3);
crypto_hash_sha3256_update(&state2, msg_abc, 3);
ret = crypto_hash_sha3256_final(&state, out);
assert(ret == 0);
ret = crypto_hash_sha3256_final(&state2, out);
assert(ret == 0);
ret = crypto_hash_sha3256_final(&state, repeated_out1);
assert(ret == -1);
ret = crypto_hash_sha3256_final(&state2, repeated_out2);
assert(ret == -1);
assert(memcmp(repeated_out1, repeated_out2, TEST_SHA3_256_BYTES) == 0);
assert(memcmp(repeated_out1, out, TEST_SHA3_256_BYTES) != 0);
assert(repeated_out1[0] != 0xAA);
printf("Final-after-final test passed\n");
}
printf("OK\n");
return 0;