From e0935a046effb0a692bafdc8d5e18f5d80dd4a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= Date: Sun, 15 Nov 2015 21:16:29 +0100 Subject: New function rsa_compute_root_tr. --- ChangeLog | 10 ++++ Makefile.in | 2 +- rsa-pkcs1-sign-tr.c | 48 ++----------------- rsa-sign-tr.c | 112 +++++++++++++++++++++++++++++++++++++++++++ rsa.h | 8 ++++ testsuite/rsa-sign-tr-test.c | 4 +- 6 files changed, 137 insertions(+), 47 deletions(-) create mode 100644 rsa-sign-tr.c diff --git a/ChangeLog b/ChangeLog index 250e905d..5c45072f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2015-09-14 Niels Möller + + * rsa-sign-tr.c (rsa_compute_root_tr): New file and function. + * rsa.h: Declare it. + * rsa-pkcs1-sign-tr.c (rsa_pkcs1_sign_tr): Use rsa_compute_root_tr. + (rsa_verify_res): Deleted, replaced by rsa_compute_root_tr. + * testsuite/rsa-sign-tr-test.c (test_rsa_sign_tr): Check that + signature argument is unchanged on failure. + * Makefile.in (hogweed_SOURCES): Added rsa-sign-tr.c. + 2015-09-07 Niels Möller * testsuite/rsa-sign-tr-test.c: Drop include of nettle-internal.h. diff --git a/Makefile.in b/Makefile.in index 1bb750de..03f1177c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -144,7 +144,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \ pkcs1.c pkcs1-encrypt.c pkcs1-decrypt.c \ pkcs1-rsa-digest.c pkcs1-rsa-md5.c pkcs1-rsa-sha1.c \ pkcs1-rsa-sha256.c pkcs1-rsa-sha512.c \ - rsa.c rsa-sign.c rsa-verify.c \ + rsa.c rsa-sign.c rsa-sign-tr.c rsa-verify.c \ rsa-pkcs1-sign.c rsa-pkcs1-sign-tr.c rsa-pkcs1-verify.c \ rsa-md5-sign.c rsa-md5-verify.c \ rsa-sha1-sign.c rsa-sha1-verify.c \ diff --git a/rsa-pkcs1-sign-tr.c b/rsa-pkcs1-sign-tr.c index f2b3e45d..00094b56 100644 --- a/rsa-pkcs1-sign-tr.c +++ b/rsa-pkcs1-sign-tr.c @@ -38,26 +38,6 @@ #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, @@ -66,34 +46,14 @@ rsa_pkcs1_sign_tr(const struct rsa_public_key *pub, size_t length, const uint8_t *digest_info, mpz_t s) { - mpz_t ri, m; + mpz_t m; int ret; mpz_init(m); - if (pkcs1_rsa_digest_encode (m, key->size, length, digest_info)) - { - mpz_init (ri); - - _rsa_blind (pub, random_ctx, random, m, ri); - rsa_compute_root(key, s, m); - - if (rsa_verify_res(pub, s, m) == 0) - { - mpz_set_ui(s, 0); - ret = 0; - } - else - ret = 1; - - _rsa_unblind (pub, s, ri); - mpz_clear (ri); - } - else - { - mpz_set_ui(s, 0); - ret = 0; - } + ret = (pkcs1_rsa_digest_encode (m, key->size, length, digest_info) + && rsa_compute_root_tr (pub, key, random_ctx, random, + s, m)); mpz_clear(m); return ret; } diff --git a/rsa-sign-tr.c b/rsa-sign-tr.c new file mode 100644 index 00000000..3d80ed4e --- /dev/null +++ b/rsa-sign-tr.c @@ -0,0 +1,112 @@ +/* rsa-sign-tr.c + + Creating RSA signatures, with some additional checks. + + Copyright (C) 2001, 2015 Niels Möller + Copyright (C) 2012 Nikos Mavrogiannopoulos + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "rsa.h" + +/* Blinds m, by computing c = m r^e (mod n), for a random r. Also + returns the inverse (ri), for use by rsa_unblind. */ +static void +rsa_blind (const struct rsa_public_key *pub, + void *random_ctx, nettle_random_func *random, + mpz_t c, mpz_t ri, const mpz_t m) +{ + mpz_t r; + + mpz_init(r); + + /* c = m*(r^e) + * ri = r^(-1) + */ + do + { + nettle_mpz_random(r, random_ctx, random, pub->n); + /* invert r */ + } + while (!mpz_invert (ri, r, pub->n)); + + /* c = c*(r^e) mod n */ + mpz_powm(r, r, pub->e, pub->n); + mpz_mul(c, m, r); + mpz_fdiv_r(c, c, pub->n); + + mpz_clear(r); +} + +/* m = c ri mod n */ +static void +rsa_unblind (const struct rsa_public_key *pub, + mpz_t m, const mpz_t ri, const mpz_t c) +{ + mpz_mul(m, c, ri); + mpz_fdiv_r(m, m, pub->n); +} + +/* Checks for any errors done in the RSA computation. That avoids + * attacks which rely on faults on hardware, or even software MPI + * implementation. */ +int +rsa_compute_root_tr(const struct rsa_public_key *pub, + const struct rsa_private_key *key, + void *random_ctx, nettle_random_func *random, + mpz_t x, const mpz_t m) +{ + int res; + mpz_t t, mb, xb, ri; + + mpz_init (mb); + mpz_init (xb); + mpz_init (ri); + mpz_init (t); + + rsa_blind (pub, random_ctx, random, mb, ri, m); + + rsa_compute_root (key, xb, mb); + + mpz_powm(t, xb, pub->e, pub->n); + res = (mpz_cmp(mb, t) == 0); + + if (res) + rsa_unblind (pub, x, ri, xb); + + mpz_clear (mb); + mpz_clear (xb); + mpz_clear (ri); + mpz_clear (t); + + return res; +} diff --git a/rsa.h b/rsa.h index 44d4af94..7d50ad90 100644 --- a/rsa.h +++ b/rsa.h @@ -75,6 +75,7 @@ extern "C" { #define rsa_decrypt nettle_rsa_decrypt #define rsa_decrypt_tr nettle_rsa_decrypt_tr #define rsa_compute_root nettle_rsa_compute_root +#define rsa_compute_root_tr nettle_rsa_compute_root_tr #define rsa_generate_keypair nettle_rsa_generate_keypair #define rsa_keypair_to_sexp nettle_rsa_keypair_to_sexp #define rsa_keypair_from_sexp_alist nettle_rsa_keypair_from_sexp_alist @@ -315,6 +316,13 @@ void rsa_compute_root(const struct rsa_private_key *key, mpz_t x, const mpz_t m); +/* Safer variant, using RSA blinding, and checking the result after + CRT. */ +int +rsa_compute_root_tr(const struct rsa_public_key *pub, + const struct rsa_private_key *key, + void *random_ctx, nettle_random_func *random, + mpz_t x, const mpz_t m); /* Key generation */ diff --git a/testsuite/rsa-sign-tr-test.c b/testsuite/rsa-sign-tr-test.c index de265b2b..d50dc6b6 100644 --- a/testsuite/rsa-sign-tr-test.c +++ b/testsuite/rsa-sign-tr-test.c @@ -17,7 +17,7 @@ test_rsa_sign_tr(struct rsa_public_key *pub, knuth_lfib_init(&lfib, 1111); mpz_init(signature); - + mpz_set_ui (signature, 17); /* Try bad private key */ mpz_add_ui(key->p, key->p, 2); @@ -27,7 +27,7 @@ test_rsa_sign_tr(struct rsa_public_key *pub, mpz_sub_ui(key->p, key->p, 2); - ASSERT(!mpz_cmp_ui(signature, 0)); + ASSERT(!mpz_cmp_ui(signature, 17)); /* Try the good private key */ ASSERT(rsa_pkcs1_sign_tr(pub, key, -- cgit v1.2.1