]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Enhanced rsa_pkcs1_sign_tr() to protect against HW/software errors
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 3 Sep 2015 08:20:37 +0000 (10:20 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Mon, 7 Sep 2015 19:47:55 +0000 (21:47 +0200)
That verifies the output of the timing-resistant version of the
signing function, to make it also fault-resistant.

rsa-pkcs1-sign-tr.c

index 0f3a5a255f4b27f1be99cf288d65e49a09ed7565..f2b3e45d8ae9e488f18d4818d9e529061dca1843 100644 (file)
 #if HAVE_CONFIG_H
 # include "config.h"
 #endif
-
 #include "rsa.h"
 
 #include "pkcs1.h"
 
+/* Checks for any errors done in the RSA computation. That avoids
+ * attacks which rely on faults on hardware, or even software MPI
+ * implementation. */
+static int
+rsa_verify_res(const struct rsa_public_key *pub,
+              mpz_t s, mpz_t m)
+{
+  mpz_t t;
+  int res;
+
+  mpz_init(t);
+
+  mpz_powm(t, s, pub->e, pub->n);
+
+  res = !mpz_cmp(m, t);
+
+  mpz_clear(t);
+  return res;
+}
+
+/* Side-channel resistant version of rsa_pkcs1_sign() */
 int
 rsa_pkcs1_sign_tr(const struct rsa_public_key *pub,
                  const struct rsa_private_key *key,
@@ -46,23 +66,34 @@ rsa_pkcs1_sign_tr(const struct rsa_public_key *pub,
                  size_t length, const uint8_t *digest_info,
                  mpz_t s)
 {
-  mpz_t ri;
+  mpz_t ri, m;
+  int ret;
+
+  mpz_init(m);
 
-  if (pkcs1_rsa_digest_encode (s, key->size, length, digest_info))
+  if (pkcs1_rsa_digest_encode (m, key->size, length, digest_info))
     {
       mpz_init (ri);
 
-      _rsa_blind (pub, random_ctx, random, s, ri);
-      rsa_compute_root(key, s, s);
-      _rsa_unblind (pub, s, ri);
+      _rsa_blind (pub, random_ctx, random, m, ri);
+      rsa_compute_root(key, s, m);
 
-      mpz_clear (ri);
+      if (rsa_verify_res(pub, s, m) == 0)
+        {
+          mpz_set_ui(s, 0);
+          ret = 0;
+        }
+      else
+        ret = 1;
 
-      return 1;
+      _rsa_unblind (pub, s, ri);
+      mpz_clear (ri);
     }
   else
     {
       mpz_set_ui(s, 0);
-      return 0;
+      ret = 0;
     }    
+  mpz_clear(m);
+  return ret;
 }