From: Niels Möller Date: Mon, 14 Sep 2015 17:21:10 +0000 (+0200) Subject: New function rsa_compute_root_tr. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=69c207f2a428580b299c332edb2d1fd7eddae49e;p=thirdparty%2Fnettle.git New function rsa_compute_root_tr. --- diff --git a/ChangeLog b/ChangeLog index 5f0c17ac..df5a79fe 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-13 Niels Möller * rsa-blind.c (_rsa_blind, _rsa_unblind): Separate source and 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 896d4107..944b0183 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, @@ -71,29 +51,9 @@ rsa_pkcs1_sign_tr(const struct rsa_public_key *pub, 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, m); - 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, s); - 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..4e73f8b8 --- /dev/null +++ b/rsa-sign-tr.c @@ -0,0 +1,73 @@ +/* rsa-sign-tr.c + + Creating RSA signatures, with some additional checks. + + Copyright (C) 2015 Niels Möller + + 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" + +/* 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 eeaeaaee..43a9c19c 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,