diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-09-03 10:20:37 +0200 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2015-09-07 21:47:55 +0200 |
commit | 736e642b337875bb5ac38da57e53a9a318964364 (patch) | |
tree | bb81f6ac55572a46448172c99ff505b27296fb58 | |
parent | 4b90268a4cadbf44de41e325a8ac43858e2d43b4 (diff) | |
download | nettle-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.c | 49 |
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; } |