From 736e642b337875bb5ac38da57e53a9a318964364 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Thu, 3 Sep 2015 10:20:37 +0200 Subject: 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. --- rsa-pkcs1-sign-tr.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file 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; } -- cgit v1.2.1