Daiki Ueno ueno@gnu.org writes:
nisse@lysator.liu.se (Niels Möller) writes:
I've tried to actually enable use of this function, by replacing pss_encode_mgf1 by pss_encode_mgf1_for_test below in the pss-test.c file.
I am sorry for forgetting to update the test code after introducing the valgrind check.
It's curious that pkcs#1 v1.5 signatures don't have this particular issue, since v1.5 padding always puts the most significant 1 bit at the same position.
So I guess we'll unfortunately have to take out the valgrind magic from this test.
How about the following workaround?
The idea is: the first bytes of EM comes from MGF1, that actually comes from the underlying hash function. In this test, we know that the bytes will never be zero. Thus, clearing the "undefined" client request on the first few bytes of digest would remove the warning.
diff --git a/testsuite/pss-test.c b/testsuite/pss-test.c index 8122655..42f7843 100644 --- a/testsuite/pss-test.c +++ b/testsuite/pss-test.c @@ -2,14 +2,49 @@
#include "pss.h"
+struct nettle_hash nettle_test_sha1; +struct nettle_hash nettle_test_sha256; + #if HAVE_VALGRIND_MEMCHECK_H # include <valgrind/memcheck.h>
+/* Workaround, to prevent false-positive "Conditional jump based on + uninitialized value". mpz_import removes the leading zero limbs + from an mpz value. That logic depends on the salt input. In this + test, however, we know that the first limb of the mpz is not zero, + and the limb comes from the output of the hash function. Clear the + "undefined" request on the first few bytes corresponding to the limb. */ +static void +nettle_test_sha1_digest(struct sha1_ctx *ctx, + size_t length, + uint8_t *digest) +{ + sha1_digest(ctx, length, digest); + + /* If LENGTH equals to the digest size, the output may be placed at + the beginning of the mask generated by pss_mgf1. */ + if (length == SHA1_DIGEST_SIZE) + VALGRIND_MAKE_MEM_DEFINED (digest, sizeof (mp_limb_t)); +} + +static void +nettle_test_sha256_digest(struct sha256_ctx *ctx, + size_t length, + uint8_t *digest) +{ + sha256_digest(ctx, length, digest); + + /* If LENGTH equals to the digest size, the output may be placed at + the beginning of the mask generated by pss_mgf1. */ + if (length == SHA256_DIGEST_SIZE) + VALGRIND_MAKE_MEM_DEFINED (digest, sizeof (mp_limb_t)); +} + static void test_unmark_mpz(mpz_t m) { VALGRIND_MAKE_MEM_DEFINED (m, sizeof(*m)); - VALGRIND_MAKE_MEM_DEFINED (&m->_mp_d, sizeof(mp_limb_t) * mpz_size(m)); + VALGRIND_MAKE_MEM_DEFINED (m->_mp_d, sizeof(mp_limb_t) * mpz_size(m)); }
static int @@ -27,11 +62,16 @@ pss_encode_mgf1_for_test(mpz_t m, size_t bits,
res = pss_encode_mgf1 (m, bits, hash, salt_length, salt, digest); VALGRIND_MAKE_MEM_DEFINED (&res, sizeof(res)); + + /* DIGEST is reused in the calls to pss_verify_mgf1. */ + VALGRIND_MAKE_MEM_DEFINED (digest, hash->digest_size); test_unmark_mpz (m); return res; } #else #define pss_encode_mgf1_for_test pss_encode_mgf1 +#define nettle_test_sha1_digest nettle_sha1_digest +#define nettle_test_sha256_digest nettle_sha256_digest #endif
void @@ -42,14 +82,20 @@ test_main(void) mpz_t m; mpz_t expected;
+ memcpy(&nettle_test_sha1, &nettle_sha1, sizeof(struct nettle_hash)); + nettle_test_sha1.digest = (nettle_hash_digest_func *) nettle_test_sha1_digest; + + memcpy(&nettle_test_sha256, &nettle_sha256, sizeof(struct nettle_hash)); + nettle_test_sha256.digest = (nettle_hash_digest_func *) nettle_test_sha256_digest; + /* From ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip */ mpz_init(m); mpz_init(expected);
salt = SHEX("e3b5d5d002c1bce50c2b65ef88a188d83bce7e61"); digest = SHEX("37b66ae0445843353d47ecb0b4fd14c110e62d6a"); - ASSERT(pss_encode_mgf1(m, 1024, &nettle_sha1, - salt->length, salt->data, digest->data)); + ASSERT(pss_encode_mgf1_for_test(m, 1024, &nettle_test_sha1, + salt->length, salt->data, digest->data));
mpz_set_str(expected, "66e4672e836ad121ba244bed6576b867d9a447c28a6e66a5b87dee" @@ -87,13 +133,13 @@ test_main(void)
/* Try bad salt */ salt->data[6] = 0x00; - ASSERT(pss_encode_mgf1(m, 1024, &nettle_sha256, + ASSERT(pss_encode_mgf1(m, 1024, &nettle_test_sha256, salt->length, salt->data, digest->data)); ASSERT(mpz_cmp(m, expected) != 0);
/* Try the good salt */ salt->data[6] = 0x77; - ASSERT(pss_encode_mgf1(m, 1024, &nettle_sha256, + ASSERT(pss_encode_mgf1(m, 1024, &nettle_test_sha256, salt->length, salt->data, digest->data)); ASSERT(mpz_cmp(m, expected) == 0);
Regards,