summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2015-09-03 10:20:37 +0200
committerNiels Möller <nisse@lysator.liu.se>2015-09-07 21:47:55 +0200
commit736e642b337875bb5ac38da57e53a9a318964364 (patch)
treebb81f6ac55572a46448172c99ff505b27296fb58
parent4b90268a4cadbf44de41e325a8ac43858e2d43b4 (diff)
downloadnettle-736e642b337875bb5ac38da57e53a9a318964364.tar.gz
Enhanced rsa_pkcs1_sign_tr() to protect against HW/software errors
That verifies the output of the timing-resistant version of the signing function, to make it also fault-resistant.
-rw-r--r--rsa-pkcs1-sign-tr.c49
1 files changed, 40 insertions, 9 deletions
diff --git a/rsa-pkcs1-sign-tr.c b/rsa-pkcs1-sign-tr.c
index 0f3a5a25..f2b3e45d 100644
--- a/rsa-pkcs1-sign-tr.c
+++ b/rsa-pkcs1-sign-tr.c
@@ -34,11 +34,31 @@
#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;
}