From 5eb30d94f6f5f3f0cb9ba9ed24bc52b7376176b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Sun, 31 Jul 2016 10:32:22 +0200
Subject: [PATCH] Reject invalid RSA keys with even modulo.

---
 ChangeLog            |  6 ++++++
 rsa.c                | 11 ++++++++---
 testsuite/rsa-test.c |  7 +++++++
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8fd30374..83e56a0a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2016-07-31  Niels Möller  <nisse@lysator.liu.se>
+
+	* rsa.c (_rsa_check_size): Check that n is odd. Otherwise, using
+	an invalid key may crash in mpz_powm_sec. Problem reported by
+	Hanno Böck.
+
 2016-07-13  Niels Möller  <nisse@lysator.liu.se>
 
 	* bignum.c (nettle_mpz_from_octets): Unconditionally use
diff --git a/rsa.c b/rsa.c
index 19d93de7..f5941409 100644
--- a/rsa.c
+++ b/rsa.c
@@ -58,13 +58,18 @@ rsa_public_key_clear(struct rsa_public_key *key)
 }
 
 /* Computes the size, in octets, of a the modulo. Returns 0 if the
- * modulo is too small to be useful. */
-
+ * modulo is too small to be useful, or otherwise appears invalid. */
 size_t
 _rsa_check_size(mpz_t n)
 {
   /* Round upwards */
-  size_t size = (mpz_sizeinbase(n, 2) + 7) / 8;
+  size_t size;
+
+  /* Even moduli are invalid, and not supported by mpz_powm_sec. */
+  if (mpz_even_p (n))
+    return 0;
+
+  size = (mpz_sizeinbase(n, 2) + 7) / 8;
 
   if (size < RSA_MINIMUM_N_OCTETS)
     return 0;
diff --git a/testsuite/rsa-test.c b/testsuite/rsa-test.c
index e9b1c030..a4296646 100644
--- a/testsuite/rsa-test.c
+++ b/testsuite/rsa-test.c
@@ -57,6 +57,13 @@ test_main(void)
 
   test_rsa_sha512(&pub, &key, expected);
 
+  /* Test detection of invalid keys with even modulo */
+  mpz_clrbit (pub.n, 0);
+  ASSERT (!rsa_public_key_prepare (&pub));
+
+  mpz_clrbit (key.p, 0);
+  ASSERT (!rsa_private_key_prepare (&key));
+
   /* 777-bit key, generated by
    *
    *   lsh-keygen -a rsa -l 777 -f advanced-hex
-- 
GitLab