From 8254d10bc802bbde72093a1e295c85afba236d96 Mon Sep 17 00:00:00 2001 From: "nelson%bolyard.com" Date: Sun, 2 May 2010 22:31:06 +0000 Subject: [PATCH] Bug 536389: ECC wrong point multiplication (=> wrong signatures) case Patch contributed by Konstantin Andreev , r=nelson git-svn-id: svn://10.0.0.236/trunk@260254 18797224-902f-48f8-a5cc-f745e15eee43 --- .../security/nss/lib/freebl/ecl/ecp_mont.c | 6 ++-- .../security/nss/lib/freebl/mpi/mpi-priv.h | 3 +- mozilla/security/nss/lib/freebl/mpi/mpi.c | 4 +-- mozilla/security/nss/lib/freebl/mpi/mpmontg.c | 32 +++++++++++-------- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/mozilla/security/nss/lib/freebl/ecl/ecp_mont.c b/mozilla/security/nss/lib/freebl/ecl/ecp_mont.c index c8829b6d157..c64bc18a771 100644 --- a/mozilla/security/nss/lib/freebl/ecl/ecp_mont.c +++ b/mozilla/security/nss/lib/freebl/ecl/ecp_mont.c @@ -77,9 +77,6 @@ GFMethod_consGFp_mont(const mp_int *irr) meth->extra_free = &ec_GFp_extra_free_mont; mmm->N = meth->irr; - i = mpl_significant_bits(&meth->irr); - i += MP_DIGIT_BIT - 1; - mmm->b = i - i % MP_DIGIT_BIT; mmm->n0prime = 0 - s_mp_invmod_radix(MP_DIGIT(&meth->irr, 0)); CLEANUP: @@ -160,7 +157,8 @@ ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth) mp_err res = MP_OKAY; mmm = (mp_mont_modulus *) meth->extra1; - MP_CHECKOK(mpl_lsh(a, r, mmm->b)); + MP_CHECKOK(mp_copy(a, r)); + MP_CHECKOK(s_mp_lshd(r, MP_USED(&mmm->N))); MP_CHECKOK(mp_mod(r, &mmm->N, r)); CLEANUP: return res; diff --git a/mozilla/security/nss/lib/freebl/mpi/mpi-priv.h b/mozilla/security/nss/lib/freebl/mpi/mpi-priv.h index 32c862e4241..8a8a529a01f 100644 --- a/mozilla/security/nss/lib/freebl/mpi/mpi-priv.h +++ b/mozilla/security/nss/lib/freebl/mpi/mpi-priv.h @@ -42,7 +42,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: mpi-priv.h,v 1.21 2009-03-19 02:26:48 julien.pierre.boogz%sun.com Exp $ */ +/* $Id: mpi-priv.h,v 1.22 2010-05-02 22:31:05 nelson%bolyard.com Exp $ */ #ifndef _MPI_PRIV_H_ #define _MPI_PRIV_H_ 1 @@ -294,7 +294,6 @@ mp_err MPI_ASM_DECL s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, typedef struct { mp_int N; /* modulus N */ mp_digit n0prime; /* n0' = - (n0 ** -1) mod MP_RADIX */ - mp_size b; /* R == 2 ** b, also b = # significant bits in N */ } mp_mont_modulus; mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c, diff --git a/mozilla/security/nss/lib/freebl/mpi/mpi.c b/mozilla/security/nss/lib/freebl/mpi/mpi.c index 431377fe222..cc7e26a2c88 100644 --- a/mozilla/security/nss/lib/freebl/mpi/mpi.c +++ b/mozilla/security/nss/lib/freebl/mpi/mpi.c @@ -40,7 +40,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: mpi.c,v 1.45 2006-09-29 20:12:21 alexei.volkov.bugs%sun.com Exp $ */ +/* $Id: mpi.c,v 1.46 2010-05-02 22:31:05 nelson%bolyard.com Exp $ */ #include "mpi-priv.h" #if defined(OSF1) @@ -2939,8 +2939,6 @@ void s_mp_exch(mp_int *a, mp_int *b) Shift mp leftward by p digits, growing if needed, and zero-filling the in-shifted digits at the right end. This is a convenient alternative to multiplication by powers of the radix - The value of USED(mp) must already have been set to the value for - the shifted result. */ mp_err s_mp_lshd(mp_int *mp, mp_size p) diff --git a/mozilla/security/nss/lib/freebl/mpi/mpmontg.c b/mozilla/security/nss/lib/freebl/mpi/mpmontg.c index f6b4ed4ba14..b8c7d68a450 100644 --- a/mozilla/security/nss/lib/freebl/mpi/mpmontg.c +++ b/mozilla/security/nss/lib/freebl/mpi/mpmontg.c @@ -36,11 +36,11 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: mpmontg.c,v 1.20 2006-08-29 02:41:38 nelson%bolyard.com Exp $ */ +/* $Id: mpmontg.c,v 1.21 2010-05-02 22:31:06 nelson%bolyard.com Exp $ */ /* This file implements moduluar exponentiation using Montgomery's * method for modular reduction. This file implements the method - * described as "Improvement 1" in the paper "A Cryptogrpahic Library for + * described as "Improvement 2" in the paper "A Cryptogrpahic Library for * the Motorola DSP56000" by Stephen R. Dusse' and Burton S. Kaliski Jr. * published in "Advances in Cryptology: Proceedings of EUROCRYPT '90" * "Lecture Notes in Computer Science" volume 473, 1991, pg 230-244, @@ -76,13 +76,15 @@ #define ABORT abort() #endif -/* computes T = REDC(T), 2^b == R */ +/*! computes T = REDC(T), 2^b == R + \param T < RN +*/ mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm) { mp_err res; mp_size i; - i = MP_USED(T) + MP_USED(&mmm->N) + 2; + i = (MP_USED(&mmm->N) << 1) + 1; MP_CHECKOK( s_mp_pad(T, i) ); for (i = 0; i < MP_USED(&mmm->N); ++i ) { mp_digit m_i = MP_DIGIT(T, i) * mmm->n0prime; @@ -92,7 +94,7 @@ mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm) s_mp_clamp(T); /* T /= R */ - s_mp_div_2d(T, mmm->b); + s_mp_rshd( T, MP_USED(&mmm->N) ); if ((res = s_mp_cmp(T, &mmm->N)) >= 0) { /* T = T - N */ @@ -109,14 +111,20 @@ CLEANUP: return res; } -#if !defined(MP_ASSEMBLY_MUL_MONT) && !defined(MP_MONT_USE_MP_MUL) +#if !defined(MP_MONT_USE_MP_MUL) + +/*! c <- REDC( a * b ) mod N + \param a < N i.e. "reduced" + \param b < N i.e. "reduced" + \param mmm modulus N and n0' of N +*/ mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c, mp_mont_modulus *mmm) { mp_digit *pb; mp_digit m_i; mp_err res; - mp_size ib; + mp_size ib; /* "index b": index of current digit of B */ mp_size useda, usedb; ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); @@ -128,7 +136,7 @@ mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c, } MP_USED(c) = 1; MP_DIGIT(c, 0) = 0; - ib = MP_USED(a) + MP_MAX(MP_USED(b), MP_USED(&mmm->N)) + 2; + ib = (MP_USED(&mmm->N) << 1) + 1; if((res = s_mp_pad(c, ib)) != MP_OKAY) goto CLEANUP; @@ -157,7 +165,7 @@ mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c, } } s_mp_clamp(c); - s_mp_div_2d(c, mmm->b); + s_mp_rshd( c, MP_USED(&mmm->N) ); /* c /= R */ if (s_mp_cmp(c, &mmm->N) >= 0) { MP_CHECKOK( s_mp_sub(c, &mmm->N) ); } @@ -174,7 +182,8 @@ mp_err s_mp_to_mont(const mp_int *x, mp_mont_modulus *mmm, mp_int *xMont) mp_err res; /* xMont = x * R mod N where N is modulus */ - MP_CHECKOK( mpl_lsh(x, xMont, mmm->b) ); /* xMont = x << b */ + MP_CHECKOK( mp_copy( x, xMont ) ); + MP_CHECKOK( s_mp_lshd( xMont, MP_USED(&mmm->N) ) ); /* xMont = x << b */ MP_CHECKOK( mp_div(xMont, &mmm->N, 0, xMont) ); /* mod N */ CLEANUP: return res; @@ -1109,9 +1118,6 @@ mp_err mp_exptmod(const mp_int *inBase, const mp_int *exponent, MP_CHECKOK( mp_init_size(&montBase, 2 * nLen + 2) ); mmm.N = *modulus; /* a copy of the mp_int struct */ - i = mpl_significant_bits(modulus); - i += MP_DIGIT_BIT - 1; - mmm.b = i - i % MP_DIGIT_BIT; /* compute n0', given n0, n0' = -(n0 ** -1) mod MP_RADIX ** where n0 = least significant mp_digit of N, the modulus.