From eb4c86c4607df940e6319a0bdefb1492f1324b76 Mon Sep 17 00:00:00 2001 From: Simo Sorce <simo@redhat.com> Date: Fri, 9 Nov 2018 17:32:04 -0500 Subject: [PATCH] Randomzed testing of rsa-sec-compute-root Signed-off-by: Simo Sorce <simo@redhat.com> --- testsuite/.gitignore | 1 + testsuite/.test-rules.make | 3 + testsuite/Makefile.in | 1 + testsuite/rsa-sec-compute-root-test.c | 229 ++++++++++++++++++++++++++ 4 files changed, 234 insertions(+) create mode 100644 testsuite/rsa-sec-compute-root-test.c diff --git a/testsuite/.gitignore b/testsuite/.gitignore index 53ffff96..b140ee34 100644 --- a/testsuite/.gitignore +++ b/testsuite/.gitignore @@ -66,6 +66,7 @@ /random-prime-test /ripemd160-test /rsa-sec-decrypt-test +/rsa-sec-compute-root-test /rsa-encrypt-test /rsa-keygen-test /rsa-pss-sign-tr-test diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make index cc03851e..9b329b5f 100644 --- a/testsuite/.test-rules.make +++ b/testsuite/.test-rules.make @@ -214,6 +214,9 @@ rsa-keygen-test$(EXEEXT): rsa-keygen-test.$(OBJEXT) rsa-sec-decrypt-test$(EXEEXT): rsa-sec-decrypt-test.$(OBJEXT) $(LINK) rsa-sec-decrypt-test.$(OBJEXT) $(TEST_OBJS) -o rsa-sec-decrypt-test$(EXEEXT) +rsa-sec-compute-root-test$(EXEEXT): rsa-sec-compute-root-test.$(OBJEXT) + $(LINK) rsa-sec-compute-root-test.$(OBJEXT) $(TEST_OBJS) -o rsa-sec-compute-root-test$(EXEEXT) + dsa-test$(EXEEXT): dsa-test.$(OBJEXT) $(LINK) dsa-test.$(OBJEXT) $(TEST_OBJS) -o dsa-test$(EXEEXT) diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index ecb2f69f..5a4174e9 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -41,6 +41,7 @@ TS_HOGWEED_SOURCES = sexp-test.c sexp-format-test.c \ pss-mgf1-test.c rsa-pss-sign-tr-test.c \ rsa-test.c rsa-encrypt-test.c rsa-keygen-test.c \ rsa-sec-decrypt-test.c \ + rsa-sec-compute-root-test.c \ dsa-test.c dsa-keygen-test.c \ curve25519-dh-test.c \ ecc-mod-test.c ecc-modinv-test.c ecc-redc-test.c \ diff --git a/testsuite/rsa-sec-compute-root-test.c b/testsuite/rsa-sec-compute-root-test.c new file mode 100644 index 00000000..baaa7ff4 --- /dev/null +++ b/testsuite/rsa-sec-compute-root-test.c @@ -0,0 +1,229 @@ +#include "testutils.h" + +#include <assert.h> +#include <errno.h> +#include <limits.h> +#include <sys/time.h> + +#include "rsa.h" + +#define COUNT 5000 + +static void +random_fn (void *ctx, size_t n, uint8_t *dst) +{ + gmp_randstate_t *rands = (gmp_randstate_t *)ctx; + mpz_t r; + + mpz_init (r); + mpz_urandomb (r, *rands, n*8); + nettle_mpz_get_str_256 (n, dst, r); + mpz_clear (r); +} + +static void +test_one (gmp_randstate_t *rands, struct rsa_public_key *pub, + struct rsa_private_key *key, mpz_t plaintext) +{ + mpz_t ciphertext; + mpz_t decrypted; + + mpz_init (ciphertext); + mpz_init (decrypted); + + mpz_powm (ciphertext, plaintext, pub->e, pub->n); + rsa_compute_root_tr (pub, key, rands, random_fn, decrypted, ciphertext); + if (mpz_cmp (plaintext, decrypted)) { + fprintf (stderr, "rsa_sec_compute_root_tr failed\n"); + + fprintf(stderr, "Public key: size=%lu\n n:", pub->size); + mpz_out_str (stderr, 10, pub->n); + fprintf(stderr, "\n e:"); + mpz_out_str (stderr, 10, pub->e); + fprintf(stderr, "\nPrivate key: size=%lu\n p:", key->size); + mpz_out_str (stderr, 10, key->p); + fprintf(stderr, "\n q:"); + mpz_out_str (stderr, 10, key->q); + fprintf(stderr, "\n a:"); + mpz_out_str (stderr, 10, key->a); + fprintf(stderr, "\n b:"); + mpz_out_str (stderr, 10, key->b); + fprintf(stderr, "\n c:"); + mpz_out_str (stderr, 10, key->c); + fprintf(stderr, "\n d:"); + mpz_out_str (stderr, 10, key->d); + fprintf(stderr, "\n"); + + fprintf (stderr, "plaintext(%lu) = ", mpz_sizeinbase (plaintext, 2)); + mpn_out_str (stderr, 16, mpz_limbs_read (plaintext), mpz_size (plaintext)); + fprintf (stderr, "\n"); + fprintf (stderr, "decrypted(%lu) = ", mpz_sizeinbase (decrypted, 2)); + mpn_out_str (stderr, 16, mpz_limbs_read (decrypted), mpz_size (decrypted)); + fprintf (stderr, "\n"); + abort(); + } +} + +#if !NETTLE_USE_MINI_GMP +/* we want to generate keypairs that are not "standard" but have more size + * variance between q and p. + * Function is otheriwse the same as standard rsa_generate_keypair() + */ +static void +generate_keypair (gmp_randstate_t *rands, + struct rsa_public_key *pub, struct rsa_private_key *key) +{ + unsigned long int psize = 0; + unsigned long int qsize = 0; + mpz_t p1; + mpz_t q1; + mpz_t phi; + mpz_t tmp; + + mpz_init (p1); + mpz_init (q1); + mpz_init (phi); + mpz_init (tmp); + + while (psize < 100) + { + mpz_set_ui(tmp, 500); + mpz_urandomm (tmp, *rands, tmp); + psize = mpz_get_ui (tmp); + } + while (qsize < 100) + { + mpz_set_ui(tmp, 500); + mpz_urandomm (tmp, *rands, tmp); + qsize = mpz_get_ui (tmp); + } + + mpz_set_ui (pub->e, 65537); + + for (;;) + { + for (;;) + { + mpz_rrandomb (key->p, *rands, psize); + mpz_nextprime (key->p, key->p); + mpz_sub_ui (p1, key->p, 1); + mpz_gcd (tmp, pub->e, p1); + if (mpz_cmp_ui (tmp, 1) == 0) + break; + } + + for (;;) + { + mpz_rrandomb (key->q, *rands, psize); + mpz_nextprime (key->q, key->q); + mpz_sub_ui (q1, key->q, 1); + mpz_gcd (tmp, pub->e, q1); + if (mpz_cmp_ui (tmp, 1) == 0) + break; + } + + if (mpz_invert (key->c, key->q, key->p)) + break; + } + + mpz_mul(phi, p1, q1); + assert (mpz_invert(key->d, pub->e, phi)); + + mpz_fdiv_r (key->a, key->d, p1); + mpz_fdiv_r (key->b, key->d, q1); + + mpz_mul (pub->n, key->p, key->q); + + pub->size = key->size = mpz_size(pub->n) * sizeof(mp_limb_t); + + mpz_clear (tmp); + mpz_clear (phi); + mpz_clear (q1); + mpz_clear (p1); +} +#endif + +#if !NETTLE_USE_MINI_GMP +static void +get_random_seed(mpz_t seed) +{ + struct timeval tv; + FILE *f; + f = fopen ("/dev/urandom", "rb"); + if (f) + { + uint8_t buf[8]; + size_t res; + + setbuf (f, NULL); + res = fread (&buf, sizeof(buf), 1, f); + fclose(f); + if (res == 1) + { + nettle_mpz_set_str_256_u (seed, sizeof(buf), buf); + return; + } + fprintf (stderr, "Read of /dev/urandom failed: %s\n", + strerror (errno)); + } + gettimeofday(&tv, NULL); + mpz_set_ui (seed, tv.tv_sec); + mpz_mul_ui (seed, seed, 1000000UL); + mpz_add_ui (seed, seed, tv.tv_usec); +} +#endif /* !NETTLE_USE_MINI_GMP */ + +void +test_main (void) +{ + const char *nettle_test_seed; + gmp_randstate_t rands; + struct rsa_public_key pub; + struct rsa_private_key key; + mpz_t plaintext; + unsigned i; + + rsa_private_key_init(&key); + rsa_public_key_init(&pub); + + gmp_randinit_default (rands); + +#if !NETTLE_USE_MINI_GMP + nettle_test_seed = getenv ("NETTLE_TEST_SEED"); + if (nettle_test_seed && *nettle_test_seed) + { + mpz_t seed; + mpz_init (seed); + if (mpz_set_str (seed, nettle_test_seed, 0) < 0 + || mpz_sgn (seed) < 0) + die ("Invalid NETTLE_TEST_SEED: %s\n", + nettle_test_seed); + if (mpz_sgn (seed) == 0) + get_random_seed (seed); + fprintf (stderr, "Using NETTLE_TEST_SEED="); + mpz_out_str (stderr, 10, seed); + fprintf (stderr, "\n"); + + gmp_randseed (rands, seed); + mpz_clear (seed); + } + + generate_keypair(&rands, &pub, &key); +#else + rsa_generate_keypair(&pub, &key, &rands, random_fn, NULL, NULL, 512, 16); +#endif /* !NETTLE_USE_MINI_GMP */ + + mpz_init (plaintext); + for (i = 0; i < COUNT; i++) + { + mpz_urandomb(plaintext, rands, mpz_sizeinbase(pub.n, 2) - 1); + test_one(&rands, &pub, &key, plaintext); + } + for (i = 0; i < COUNT; i++) + { + mpz_rrandomb(plaintext, rands, mpz_sizeinbase(pub.n, 2) - 1); + test_one(&rands, &pub, &key, plaintext); + } + + gmp_randclear (rands); +} -- GitLab