From: Niels Möller Date: Sun, 16 Feb 2025 19:54:41 +0000 (+0100) Subject: Add tests of side-channel silence of slh-dsa primitives. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7620fcc376ce280d8a93ef50b08daef2accf2844;p=thirdparty%2Fnettle.git Add tests of side-channel silence of slh-dsa primitives. --- diff --git a/ChangeLog b/ChangeLog index 32a30c1a..cbe963d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2025-02-16 Niels Möller + + * testsuite/Makefile.in (TS_SC_HOGWEED): Add sc-slh-dsa-test. + + * testsuite/sc-slh-dsa-test: New test case. + * testsuite/slh-dsa-test.c: Add mark_bytes_undefined / + mark_bytes_defined instrumentation to tests of the slh-dsa + primitives. + 2025-02-14 Niels Möller * slh-dsa.h: New public header file. diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index 396eece3..cf3122f8 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -73,7 +73,8 @@ TARGETS = $(TS_C) $(TS_CXX) TS_SC_HOGWEED = sc-pkcs1-sec-decrypt-test sc-rsa-sec-decrypt-test \ sc-rsa-oaep-encrypt-test \ sc-ecdsa-sign-test sc-curve25519-dh-test sc-curve448-dh-test \ - sc-ed25519-test sc-ed448-test + sc-ed25519-test sc-ed448-test sc-slh-dsa-test + TS_SC_NETTLE = sc-cnd-memcpy-test sc-gcm-test sc-memeql-test TS_SC = @IF_VALGRIND@ $(TS_SC_NETTLE) @IF_HOGWEED@ $(TS_SC_HOGWEED) diff --git a/testsuite/sc-slh-dsa-test b/testsuite/sc-slh-dsa-test new file mode 100755 index 00000000..9496dc9d --- /dev/null +++ b/testsuite/sc-slh-dsa-test @@ -0,0 +1,6 @@ +#! /bin/sh + +srcdir=`dirname $0` +. "${srcdir}/sc-valgrind.sh" + +with_valgrind ./slh-dsa-test diff --git a/testsuite/slh-dsa-test.c b/testsuite/slh-dsa-test.c index a70db816..b18cfa81 100644 --- a/testsuite/slh-dsa-test.c +++ b/testsuite/slh-dsa-test.c @@ -50,6 +50,7 @@ test_wots_gen (const struct tstring *public_seed, const struct tstring *secret_s at.layer = bswap32_if_le (layer); at.tree_idx = bswap64_if_le (tree_idx); _wots_gen (public_seed->data, secret_seed->data, &at, keypair, pub); + mark_bytes_defined (sizeof (pub), pub); ASSERT (MEMEQ (sizeof (pub), pub, exp_pub->data)); } @@ -72,6 +73,8 @@ test_wots_sign (const struct tstring *public_seed, const struct tstring *secret_ _wots_sign (public_seed->data, secret_seed->data, &at, keypair, msg->data, sig, pub); + mark_bytes_defined (sizeof(sig), sig); + mark_bytes_defined (sizeof(pub), pub); ASSERT (MEMEQ(sizeof(sig), sig, exp_sig->data)); ASSERT (MEMEQ(sizeof(pub), pub, exp_pub->data)); @@ -85,6 +88,7 @@ static void xmss_leaf (const struct slh_merkle_ctx_secret *ctx, unsigned idx, uint8_t *leaf) { _wots_gen (ctx->pub.seed, ctx->secret_seed, &ctx->pub.at, idx, leaf); + mark_bytes_defined (SLH_DSA_SHAKE_128S_SEED_SIZE, leaf); } static void @@ -159,6 +163,8 @@ test_fors_gen(const struct tstring *public_seed, const struct tstring *secret_se ASSERT (exp_leaf->length == _SLH_DSA_128_SIZE); _fors_gen (&ctx, idx, sk, leaf); + mark_bytes_defined (sizeof(sk), sk); + mark_bytes_defined (sizeof(sk), leaf); ASSERT (MEMEQ(sizeof(sk), sk, exp_sk->data)); ASSERT (MEMEQ(sizeof(leaf), leaf, exp_leaf->data)); } @@ -186,6 +192,8 @@ test_fors_sign (const struct tstring *public_seed, const struct tstring *secret_ ASSERT (exp_sig->length == FORS_SIGNATURE_SIZE); _fors_sign (&ctx, msg->data, sig, pub); + mark_bytes_defined (sizeof(sig), sig); + mark_bytes_defined (sizeof(pub), pub); ASSERT (MEMEQ(sizeof(sig), sig, exp_sig->data)); ASSERT (MEMEQ(sizeof(pub), pub, exp_pub->data)); @@ -204,6 +212,7 @@ test_xmss_gen(const struct tstring *public_seed, const struct tstring *secret_se ASSERT (exp_pub->length == _SLH_DSA_128_SIZE); _xmss_gen (public_seed->data, secret_seed->data, pub); + mark_bytes_defined (sizeof(pub), pub); ASSERT (MEMEQ(sizeof(pub), pub, exp_pub->data)); } @@ -231,6 +240,8 @@ test_xmss_sign (const struct tstring *public_seed, const struct tstring *secret_ ASSERT (exp_sig->length == XMSS_SIGNATURE_SIZE); _xmss_sign (&ctx, idx, msg->data, sig, pub); + mark_bytes_defined (sizeof(pub), pub); + mark_bytes_defined (sizeof(sig), sig); ASSERT (MEMEQ(sizeof(sig), sig, exp_sig->data)); ASSERT (MEMEQ(sizeof(pub), pub, exp_pub->data)); @@ -276,6 +287,8 @@ test_main(void) const struct tstring *secret_seed = SHEX("7c9935a0b07694aa0c6d10e4db6b1add"); + mark_bytes_undefined (2*SLH_DSA_SHAKE_128S_SEED_SIZE, secret_seed->data); + test_wots_gen (public_seed, secret_seed, 6, 0, 0, SHEX("38c9077d76d1e32933fb58a53e769ed7")); test_wots_gen (public_seed, secret_seed, 6, 0, 1, @@ -455,6 +468,14 @@ test_main(void) "a467897bbed0d3a0 9d50e9deaadff78d e9ac65c1fd05d076 10a79c8c465141ad" "65e60340531fab08 f1f433ef823283fe")); + /* If we mark the private key for the top-level + slh_dsa_shake_128s_sign call as undefined, then we get valgrind + errors from the branches in wots_chain, when signing the derived + public keys. We'd need further instrumentation to make such a + test work. */ + if (test_side_channel) + return; + /* Test vector from https://github.com/smuellerDD/leancrypto/raw/refs/heads/master/slh-dsa/tests/sphincs_tester_vectors_shake_128s.h */ test_slh_dsa_shake_128s(SHEX("B505D7CFAD1B4974 99323C8686325E47"