diff --git a/mpi/Makefile.am b/mpi/Makefile.am index 5edd90c28..353ab23a2 100644 --- a/mpi/Makefile.am +++ b/mpi/Makefile.am @@ -1,27 +1,36 @@ ## Process this file with automake to produce Makefile.in INCLUDES = -I$(top_srcdir)/include +CFLAGS += -O2 noinst_LIBRARIES = mpi -mpi_SOURCES = longlong.h \ - mpi-add.c \ - mpi-bit.c \ - mpi-cmp.c \ - mpi-div.c \ - mpi-gcd.c \ - mpi-internal.h \ - mpi-inv.c \ - mpi-mul.c \ - mpi-pow.c \ - mpi-scan.c \ - mpicoder.c \ - mpihelp-add.c \ - mpihelp-cmp.c \ - mpihelp-div.c \ - mpihelp-mul.c \ - mpihelp-shift.c \ - mpihelp-sub.c \ +mpi_SOURCES = longlong.h \ + mpi-add.c \ + mpi-bit.c \ + mpi-cmp.c \ + mpi-div.c \ + mpi-gcd.c \ + mpi-internal.h \ + mpi-inline.h \ + mpi-inv.c \ + mpi-mul.c \ + mpi-pow.c \ + mpi-scan.c \ + mpicoder.c \ + mpih-add.c \ + mpih-cmp.c \ + mpih-div.c \ + mpih-mul.c \ + mpih-shift.c \ + mpih-sub.c \ + mpih-mul1.S \ + mpih-mul2.S \ + mpih-add1.S \ + mpih-mul3.S \ + mpih-sub1.S \ + mpih-shift.S \ + mpih-add.S \ mpiutil.c diff --git a/mpi/mpi-add.c b/mpi/mpi-add.c index b9c69af44..70fc31208 100644 --- a/mpi/mpi-add.c +++ b/mpi/mpi-add.c @@ -1,5 +1,6 @@ /* mpi-add.c - MPI functions * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. * * This file is part of G10. * @@ -16,6 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. */ #include diff --git a/mpi/mpi-div.c b/mpi/mpi-div.c index 2955575a8..2b39cb4cf 100644 --- a/mpi/mpi-div.c +++ b/mpi/mpi-div.c @@ -1,5 +1,6 @@ /* mpi-div.c - MPI functions * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. * * This file is part of G10. * @@ -16,6 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. */ #include @@ -189,7 +198,7 @@ mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den) /* Make sure QP and NP point to different objects. Otherwise the * numerator would be gradually overwritten by the quotient limbs. */ if(qp == np) { /* Copy NP object to temporary space. */ - np = marker[markidx++] = mpi_alloc_limb_space(nsize); + np = marker[markidx++] = mpi_alloc_limb_space(nsize,quot->secure); MPN_COPY(np, qp, nsize); } } @@ -209,7 +218,7 @@ mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den) /* Shift up the denominator setting the most significant bit of * the most significant word. Use temporary storage not to clobber * the original contents of the denominator. */ - tp = marker[markidx++] = mpi_alloc_limb_space(dsize); + tp = marker[markidx++] = mpi_alloc_limb_space(dsize,den->secure); mpihelp_lshift( tp, dp, dsize, normalization_steps ); dp = tp; @@ -230,7 +239,7 @@ mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den) if( dp == rp || (quot && (dp == qp))) { mpi_ptr_t tp; - tp = marker[markidx++] = mpi_alloc_limb_space(dsize); + tp = marker[markidx++] = mpi_alloc_limb_space(dsize, den->secure); MPN_COPY( tp, dp, dsize ); dp = tp; } diff --git a/mpi/mpi-inline.h b/mpi/mpi-inline.h new file mode 100644 index 000000000..4d19942ad --- /dev/null +++ b/mpi/mpi-inline.h @@ -0,0 +1,127 @@ +/* mpi-inline.h - Internal to the Multi Precision Integers + * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. + * + * This file is part of G10. + * + * G10 is free software; you can redistribute it and/or modify + * it under the terms of 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. + * + * G10 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 a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. + */ + +#ifndef G10_MPI_INLINE_H +#define G10_MPI_INLINE_H + + +extern __inline__ mpi_limb_t +mpihelp_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, + mpi_size_t s1_size, mpi_limb_t s2_limb) +{ + mpi_limb_t x; + + x = *s1_ptr++; + s2_limb += x; + *res_ptr++ = s2_limb; + if( s2_limb < x ) { /* sum is less than the left operand: handle carry */ + while( --s1_size ) { + x = *s1_ptr++ + 1; /* add carry */ + *res_ptr++ = x; /* and store */ + if( x ) /* not 0 (no overflow): we can stop */ + goto leave; + } + return 1; /* return carry (size of s1 to small) */ + } + + leave: + if( res_ptr != s1_ptr ) { /* not the same variable */ + mpi_size_t i; /* copy the rest */ + for( i=0; i < s1_size-1; i++ ) + res_ptr[i] = s1_ptr[i]; + } + return 0; /* no carry */ +} + + + +extern __inline__ mpi_limb_t +mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, + mpi_ptr_t s2_ptr, mpi_size_t s2_size) +{ + mpi_limb_t cy = 0; + + if( s2_size ) + cy = mpihelp_add_n( res_ptr, s1_ptr, s2_ptr, s2_size ); + + if( s1_size - s2_size ) + cy = mpihelp_add_1( res_ptr + s2_size, s1_ptr + s2_size, + s1_size - s2_size, cy); + return cy; +} + + +extern __inline__ mpi_limb_t +mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, + mpi_size_t s1_size, mpi_limb_t s2_limb ) +{ + mpi_limb_t x; + + x = *s1_ptr++; + s2_limb = x - s2_limb; + *res_ptr++ = s2_limb; + if( s2_limb > x ) { + while( --s1_size ) { + x = *s1_ptr++; + *res_ptr++ = x - 1; + if( x ) + goto leave; + } + return 1; + } + + leave: + if( res_ptr != s1_ptr ) { + mpi_size_t i; + for( i=0; i < s1_size-1; i++ ) + res_ptr[i] = s1_ptr[i]; + } + return 0; +} + + + +extern __inline__ mpi_limb_t +mpihelp_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, + mpi_ptr_t s2_ptr, mpi_size_t s2_size) +{ + mpi_limb_t cy = 0; + + if( s2_size ) + cy = mpihelp_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size); + + if( s1_size - s2_size ) + cy = mpihelp_sub_1(res_ptr + s2_size, s1_ptr + s2_size, + s1_size - s2_size, cy); + return cy; +} + + + +#endif /*G10_MPI_INLINE_H*/ diff --git a/mpi/mpi-internal.h b/mpi/mpi-internal.h index b5c00b6c4..2748ddad9 100644 --- a/mpi/mpi-internal.h +++ b/mpi/mpi-internal.h @@ -1,5 +1,6 @@ /* mpi-internal.h - Internal to the Multi Precision Integers * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. * * This file is part of G10. * @@ -16,6 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. */ #ifndef G10_MPI_INTERNAL_H @@ -120,12 +129,12 @@ typedef int mpi_size_t; /* (must be a signed type) */ /*-- mpiutil.c --*/ #ifdef M_DEBUG - #define mpi_alloc_limb_space(n) mpi_debug_alloc_limb_space((n), M_DBGINFO( __LINE__ ) ) + #define mpi_alloc_limb_space(n,f) mpi_debug_alloc_limb_space((n),(f), M_DBGINFO( __LINE__ ) ) #define mpi_free_limb_space(n) mpi_debug_free_limb_space((n), M_DBGINFO( __LINE__ ) ) - mpi_ptr_t mpi_debug_alloc_limb_space( unsigned nlimbs, const char *info ); + mpi_ptr_t mpi_debug_alloc_limb_space( unsigned nlimbs, int sec, const char *info ); void mpi_debug_free_limb_space( mpi_ptr_t a, const char *info ); #else - mpi_ptr_t mpi_alloc_limb_space( unsigned nlimbs ); + mpi_ptr_t mpi_alloc_limb_space( unsigned nlimbs, int sec ); void mpi_free_limb_space( mpi_ptr_t a ); #endif void mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs ); @@ -154,13 +163,15 @@ mpi_limb_t mpihelp_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_limb_t s2_limb); mpi_limb_t mpihelp_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_limb_t s2_limb); -mpi_limb_t mpihelp_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb); void mpihelp_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size); mpi_limb_t mpihelp_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, mpi_ptr_t vp, mpi_size_t vsize); +/*-- mpihelp-mul_1.c (or xxx/cpu/*.S) --*/ +mpi_limb_t mpihelp_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, + mpi_size_t s1_size, mpi_limb_t s2_limb); + /*-- mpihelp-div.c --*/ mpi_limb_t mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, mpi_limb_t divisor_limb); @@ -194,5 +205,8 @@ mpi_limb_t mpihelp_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, typedef unsigned long USItype; #endif +#ifdef __GNUC__ + #include "mpi-inline.h" +#endif #endif /*G10_MPI_INTERNAL_H*/ diff --git a/mpi/mpi-mul.c b/mpi/mpi-mul.c index aa5beb73b..85ee1d8c5 100644 --- a/mpi/mpi-mul.c +++ b/mpi/mpi-mul.c @@ -1,5 +1,6 @@ /* mpi-mul.c - MPI functions * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. * * This file is part of G10. * @@ -16,6 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. */ #include @@ -107,24 +116,28 @@ mpi_mul( MPI w, MPI u, MPI v) mpi_size_t usize, vsize, wsize; mpi_ptr_t up, vp, wp; mpi_limb_t cy; - int usign, vsign, sign_product; + int usign, vsign, usecure, vsecure, sign_product; int assign_wp=0; mpi_ptr_t tmp_limb=NULL; if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */ usize = v->nlimbs; usign = v->sign; + usecure = v->secure; up = v->d; vsize = u->nlimbs; vsign = u->sign; + vsecure = u->secure; vp = u->d; } else { usize = u->nlimbs; usign = u->sign; + usecure = u->secure; up = u->d; vsize = v->nlimbs; vsign = v->sign; + vsecure = v->secure; vp = v->d; } sign_product = usign ^ vsign; @@ -134,7 +147,7 @@ mpi_mul( MPI w, MPI u, MPI v) wsize = usize + vsize; if( w->alloced < wsize ) { if( wp == up || wp == vp ) { - wp = mpi_alloc_limb_space( wsize ); + wp = mpi_alloc_limb_space( wsize, w->secure ); assign_wp = 1; } else { @@ -145,7 +158,7 @@ mpi_mul( MPI w, MPI u, MPI v) else { /* Make U and V not overlap with W. */ if( wp == up ) { /* W and U are identical. Allocate temporary space for U. */ - up = tmp_limb = mpi_alloc_limb_space( usize ); + up = tmp_limb = mpi_alloc_limb_space( usize, usecure ); /* Is V identical too? Keep it identical with U. */ if( wp == vp ) vp = up; @@ -154,7 +167,7 @@ mpi_mul( MPI w, MPI u, MPI v) } else if( wp == vp ) { /* W and V are identical. Allocate temporary space for V. */ - vp = tmp_limb = mpi_alloc_limb_space( vsize ); + vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure ); /* Copy to the temporary space. */ MPN_COPY( vp, wp, vsize ); } diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c index 14fe4de47..43514567b 100644 --- a/mpi/mpi-pow.c +++ b/mpi/mpi-pow.c @@ -1,5 +1,6 @@ /* mpi-pow.c - MPI functions * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. * * This file is part of G10. * @@ -16,6 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. */ #include @@ -35,6 +44,7 @@ mpi_powm( MPI res, MPI base, MPI exp, MPI mod) mpi_ptr_t rp, ep, mp, bp; mpi_size_t esize, msize, bsize, rsize; int esign, msign, bsign, rsign; + int esec, msec, bsec, rsec; mpi_size_t size; int mod_shift_cnt; int negative_result; @@ -48,6 +58,11 @@ mpi_powm( MPI res, MPI base, MPI exp, MPI mod) esign = exp->sign; msign = mod->sign; + esec = exp->secure; + msec = mod->secure; + bsec = base->secure; + rsec = res->secure; + rp = res->d; ep = exp->d; @@ -67,7 +82,7 @@ mpi_powm( MPI res, MPI base, MPI exp, MPI mod) * mpn_divrem. This will make the intermediate values in the calculation * slightly larger, but the correct result is obtained after a final * reduction using the original MOD value. */ - mp = mp_marker = mpi_alloc_limb_space(msize); + mp = mp_marker = mpi_alloc_limb_space(msize, msec); count_leading_zeros( mod_shift_cnt, mod->d[msize-1] ); if( mod_shift_cnt ) mpihelp_lshift( mp, mod->d, msize, mod_shift_cnt ); @@ -79,7 +94,7 @@ mpi_powm( MPI res, MPI base, MPI exp, MPI mod) if( bsize > msize ) { /* The base is larger than the module. Reduce it. */ /* Allocate (BSIZE + 1) with space for remainder and quotient. * (The quotient is (bsize - msize + 1) limbs.) */ - bp = bp_marker = mpi_alloc_limb_space( bsize + 1); + bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec ); MPN_COPY( bp, base->d, bsize ); /* We don't care about the quotient, store it above the remainder, * at BP + MSIZE. */ @@ -103,7 +118,7 @@ mpi_powm( MPI res, MPI base, MPI exp, MPI mod) * parameters are identical to RES, defer deallocation of the old * space. */ if( rp == ep || rp == mp || rp == bp ) { - rp = mpi_alloc_limb_space( size ); + rp = mpi_alloc_limb_space( size, rsec ); assign_rp = 1; } else { @@ -115,18 +130,18 @@ mpi_powm( MPI res, MPI base, MPI exp, MPI mod) if( rp == bp ) { /* RES and BASE are identical. Allocate temp. space for BASE. */ assert( !bp_marker ); - bp = bp_marker = mpi_alloc_limb_space( bsize ); + bp = bp_marker = mpi_alloc_limb_space( bsize, bsec ); MPN_COPY(bp, rp, bsize); } if( rp == ep ) { /* RES and EXP are identical. Allocate temp. space for EXP. */ - ep = ep_marker = mpi_alloc_limb_space( esize ); + ep = ep_marker = mpi_alloc_limb_space( esize, esec ); MPN_COPY(ep, rp, esize); } if( rp == mp ) { /* RES and MOD are identical. Allocate temporary space for MOD.*/ assert( !mp_marker ); - mp = mp_marker = mpi_alloc_limb_space( msize ); + mp = mp_marker = mpi_alloc_limb_space( msize, msec ); MPN_COPY(mp, rp, msize); } } @@ -137,7 +152,7 @@ mpi_powm( MPI res, MPI base, MPI exp, MPI mod) { mpi_size_t i; - mpi_ptr_t xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1) ); + mpi_ptr_t xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec ); int c; mpi_limb_t e; mpi_limb_t carry_limb; diff --git a/mpi/mpih-add.c b/mpi/mpih-add.c index 90ce8d76a..c01928d14 100644 --- a/mpi/mpih-add.c +++ b/mpi/mpih-add.c @@ -1,5 +1,6 @@ /* mpihelp-add.c - MPI helper functions * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. * * This file is part of G10. * @@ -16,6 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. */ #include @@ -29,6 +38,7 @@ * store the result in RES_PTR. Return the carry * S1_SIZE must be > 0. */ +#ifndef __GNUC__ /*_EXTERN_INLINE */ mpi_limb_t mpihelp_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, @@ -59,37 +69,6 @@ mpihelp_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, } -/* FIXME: this should be done in assembly */ -mpi_limb_t -mpihelp_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_ptr_t s2_ptr, mpi_size_t size) -{ - mpi_limb_t x, y, cy; - mpi_size_t j; - - /* The loop counter and index J goes from -SIZE to -1. This way - the loop becomes faster. */ - j = -size; - - /* Offset the base pointers to compensate for the negative indices. */ - s1_ptr -= j; - s2_ptr -= j; - res_ptr -= j; - - cy = 0; - do { - y = s2_ptr[j]; - x = s1_ptr[j]; - y += cy; /* add previous carry to one addend */ - cy = y < cy? 1:0; /* get out carry from that addition */ - y += x; /* add other addend */ - cy += y < x? 1:0; /* get out carry from that add, combine */ - res_ptr[j] = y; - } while( ++j ); - - return cy; -} - /*_EXTERN_INLINE*/ mpi_limb_t @@ -106,4 +85,4 @@ mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, s1_size - s2_size, cy); return cy; } - +#endif diff --git a/mpi/mpih-cmp.c b/mpi/mpih-cmp.c index 821c0ce8c..235a1cdd9 100644 --- a/mpi/mpih-cmp.c +++ b/mpi/mpih-cmp.c @@ -1,5 +1,6 @@ /* mpihelp-sub.c - MPI helper functions * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. * * This file is part of G10. * @@ -16,6 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. */ #include diff --git a/mpi/mpih-div.c b/mpi/mpih-div.c index ca939a750..9729304ea 100644 --- a/mpi/mpih-div.c +++ b/mpi/mpih-div.c @@ -1,5 +1,6 @@ /* mpihelp-div.c - MPI helper functions * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. * * This file is part of G10. * @@ -16,6 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. */ #include diff --git a/mpi/mpih-mul.c b/mpi/mpih-mul.c index c579a93fe..0e52488ec 100644 --- a/mpi/mpih-mul.c +++ b/mpi/mpih-mul.c @@ -1,5 +1,6 @@ /* mpihelp-mul.c - MPI helper functions * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. * * This file is part of G10. * @@ -16,6 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. */ #include @@ -55,95 +64,6 @@ -mpi_limb_t -mpihelp_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb) -{ - mpi_limb_t cy_limb; - mpi_size_t j; - mpi_limb_t prod_high, prod_low; - mpi_limb_t x; - - /* The loop counter and index J goes from -SIZE to -1. This way - * the loop becomes faster. */ - j = -s1_size; - res_ptr -= j; - s1_ptr -= j; - - cy_limb = 0; - do { - umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb ); - - prod_low += cy_limb; - cy_limb = (prod_low < cy_limb?1:0) + prod_high; - - x = res_ptr[j]; - prod_low = x + prod_low; - cy_limb += prod_low < x?1:0; - res_ptr[j] = prod_low; - } while ( ++j ); - return cy_limb; -} - - -mpi_limb_t -mpihelp_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb) -{ - mpi_limb_t cy_limb; - mpi_size_t j; - mpi_limb_t prod_high, prod_low; - mpi_limb_t x; - - /* The loop counter and index J goes from -SIZE to -1. This way - * the loop becomes faster. */ - j = -s1_size; - res_ptr -= j; - s1_ptr -= j; - - cy_limb = 0; - do { - umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb); - - prod_low += cy_limb; - cy_limb = (prod_low < cy_limb?1:0) + prod_high; - - x = res_ptr[j]; - prod_low = x - prod_low; - cy_limb += prod_low > x?1:0; - res_ptr[j] = prod_low; - } while( ++j ); - - return cy_limb; -} - -mpi_limb_t -mpihelp_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, - mpi_limb_t s2_limb) -{ - mpi_limb_t cy_limb; - mpi_size_t j; - mpi_limb_t prod_high, prod_low; - - /* The loop counter and index J goes from -S1_SIZE to -1. This way - * the loop becomes faster. */ - j = -s1_size; - - /* Offset the base pointers to compensate for the negative indices. */ - s1_ptr -= j; - res_ptr -= j; - - cy_limb = 0; - do { - umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb ); - prod_low += cy_limb; - cy_limb = (prod_low < cy_limb?1:0) + prod_high; - res_ptr[j] = prod_low; - } while( ++j ); - - return cy_limb; -} - /* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP), * both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are @@ -437,12 +357,14 @@ sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace) void mpihelp_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size) { + /* FIXME: mpi_alloc_limb_space, secure arg is wrong! */ + if( up == vp ) { if( size < KARATSUBA_THRESHOLD ) sqr_n_basecase( prodp, up, size ); else { mpi_ptr_t tspace; - tspace = mpi_alloc_limb_space( 2 * size ); + tspace = mpi_alloc_limb_space( 2 * size, 0 ); sqr_n( prodp, up, size, tspace ); mpi_free_limb_space( tspace ); } @@ -452,7 +374,7 @@ mpihelp_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size) mul_n_basecase( prodp, up, vp, size ); else { mpi_ptr_t tspace; - tspace = mpi_alloc_limb_space( 2 * size ); + tspace = mpi_alloc_limb_space( 2 * size, 0 ); mul_n (prodp, up, vp, size, tspace); mpi_free_limb_space( tspace ); } @@ -525,14 +447,16 @@ mpihelp_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, return cy; } - tspace = mpi_alloc_limb_space( 2 * vsize ); + /* FIXME: mpi_alloc_limb_space, secure arg is wrong! */ + tspace = mpi_alloc_limb_space( 2 * vsize, 0 ); MPN_MUL_N_RECURSE( prodp, up, vp, vsize, tspace ); prodp += vsize; up += vsize; usize -= vsize; if( usize >= vsize ) { - mpi_ptr_t tp = mpi_alloc_limb_space( 2 * vsize ); + /* FIXME: mpi_alloc_limb_space, secure arg is wrong! */ + mpi_ptr_t tp = mpi_alloc_limb_space( 2 * vsize, 0 ); do { MPN_MUL_N_RECURSE( tp, up, vp, vsize, tspace ); cy = mpihelp_add_n( prodp, prodp, tp, vsize ); diff --git a/mpi/mpih-sub.c b/mpi/mpih-sub.c index 3831d81c3..0864ef8f0 100644 --- a/mpi/mpih-sub.c +++ b/mpi/mpih-sub.c @@ -1,5 +1,6 @@ /* mpihelp-sub.c - MPI helper functions * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1994, 1996 Free Software Foundation, Inc. * * This file is part of G10. * @@ -16,6 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. */ #include @@ -24,8 +33,7 @@ #include "mpi-internal.h" - -/*_EXTERN_INLINE*/ +#ifndef __GNUC__ mpi_limb_t mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_limb_t s2_limb ) @@ -55,39 +63,6 @@ mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, } -/* FIXME: this should be done in assembly */ -mpi_limb_t -mpihelp_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_ptr_t s2_ptr, mpi_size_t size) -{ - mpi_limb_t x, y, cy; - mpi_size_t j; - - /* The loop counter and index J goes from -SIZE to -1. This way - the loop becomes faster. */ - j = -size; - - /* Offset the base pointers to compensate for the negative indices. */ - s1_ptr -= j; - s2_ptr -= j; - res_ptr -= j; - - cy = 0; - do { - y = s2_ptr[j]; - x = s1_ptr[j]; - y += cy; /* add previous carry to subtrahend */ - cy = y < cy ? 1:0; /* get out carry from that addition */ - y = x - y; /* main subtract */ - cy += y > x? 1:0; /* get out carry from the subtract, combine */ - res_ptr[j] = y; - } while( ++j ); - - return cy; -} - - -/*_EXTERN_INLINE*/ mpi_limb_t mpihelp_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_ptr_t s2_ptr, mpi_size_t s2_size) @@ -102,5 +77,5 @@ mpihelp_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, s1_size - s2_size, cy); return cy; } - +#endif diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index 15833d3f1..0c8e648b1 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -35,20 +35,6 @@ #undef mpi_free #endif -typedef struct unused_obj { - struct unused_obj *next; - unsigned length; - union { - MPI mpi; - mpi_limb_t *limb; - } u; -} *unused_obj_t; - -static unused_obj_t unused_objs; -static unused_obj_t unused_mpis; -static unused_obj_t unused_limbs; - - MPI #ifdef M_DEBUG mpi_debug_alloc( unsigned nlimbs, const char *info ) @@ -58,34 +44,19 @@ mpi_alloc( unsigned nlimbs ) { MPI a; - if( unused_mpis ) { - unused_obj_t u; - - if( DBG_MEMORY ) - log_debug("mpi_alloc(%lu) reusing\n", nlimbs*BITS_PER_MPI_LIMB ); - a = unused_mpis->u.mpi; - u = unused_mpis; - unused_mpis = unused_mpis->next; - u->next = unused_objs; - unused_objs = u; - } - else { - if( DBG_MEMORY ) - log_debug("mpi_alloc(%lu) new\n", nlimbs*BITS_PER_MPI_LIMB ); - #ifdef M_DEBUG - a = m_debug_alloc( sizeof *a, info ); - #else - a = m_alloc( sizeof *a ); - #endif - } + if( DBG_MEMORY ) + log_debug("mpi_alloc(%lu)\n", nlimbs*BITS_PER_MPI_LIMB ); #ifdef M_DEBUG - a->d = mpi_debug_alloc_limb_space( nlimbs, info ); + a = m_debug_alloc( sizeof *a, info ); + a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 0, info ) : NULL; #else - a->d = mpi_alloc_limb_space( nlimbs ); + a = m_alloc( sizeof *a ); + a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL; #endif a->alloced = nlimbs; a->nlimbs = 0; a->sign = 0; + a->secure = 0; return a; } @@ -105,13 +76,17 @@ mpi_alloc_secure( unsigned nlimbs ) { MPI a; - a = m_alloc( sizeof *a ); + if( DBG_MEMORY ) + log_debug("mpi_alloc_secure(%lu)\n", nlimbs*BITS_PER_MPI_LIMB ); #ifdef M_DEBUG - a->d = m_debug_alloc_secure( nlimbs * sizeof(mpi_limb_t), info ); + a = m_debug_alloc( sizeof *a, info ); + a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 1, info ) : NULL; #else - a->d = m_alloc_secure( nlimbs * sizeof(mpi_limb_t) ); + a = m_alloc( sizeof *a ); + a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL; #endif a->alloced = nlimbs; + a->secure = 1; a->nlimbs = 0; a->sign = 0; return a; @@ -120,27 +95,19 @@ mpi_alloc_secure( unsigned nlimbs ) mpi_ptr_t #ifdef M_DEBUG -mpi_debug_alloc_limb_space( unsigned nlimbs, const char *info ) +mpi_debug_alloc_limb_space( unsigned nlimbs, int secure, const char *info ) #else -mpi_alloc_limb_space( unsigned nlimbs ) +mpi_alloc_limb_space( unsigned nlimbs, int secure ) #endif { - unused_obj_t u; size_t len = nlimbs * sizeof(mpi_limb_t); - for(u=unused_limbs; u; u = u->next ) - if( u->length >= len ) { - u->length = 0; - if( DBG_MEMORY ) - log_debug("mpi_alloc_limb_space(%lu) reusing\n", len*8 ); - return u->u.limb; - } if( DBG_MEMORY ) - log_debug("mpi_alloc_limb_space(%u) new\n", len*8 ); + log_debug("mpi_alloc_limb_space(%u)\n", len*8 ); #ifdef M_DEBUG - return m_debug_alloc( len, info ); + return secure? m_debug_alloc_secure(len, info):m_debug_alloc( len, info ); #else - return m_alloc( len ); + return secure? m_alloc_secure( len ):m_alloc( len ); #endif } @@ -151,27 +118,11 @@ mpi_debug_free_limb_space( mpi_ptr_t a, const char *info ) mpi_free_limb_space( mpi_ptr_t a ) #endif { - unused_obj_t u; - if( !a ) return; if( DBG_MEMORY ) log_debug("mpi_free_limb_space of size %lu\n", (ulong)m_size(a)*8 ); - for(u=unused_limbs; u; u = u->next ) - if( !u->length ) { - u->length = m_size(a); - u->u.limb = a; - return; - } - - if( (u=unused_objs) ) - unused_objs = unused_objs->next; - else - u = m_alloc( sizeof *u ); - u->length = m_size(a); - u->u.limb = a; - u->next = unused_limbs; - unused_limbs = u; + m_free(a); } @@ -198,6 +149,7 @@ mpi_resize( MPI a, unsigned nlimbs ) { if( nlimbs <= a->alloced ) return; /* no need to do it */ + /* FIXME: add realloc_secure based on a->secure */ #ifdef M_DEBUG if( a->d ) a->d = m_debug_realloc(a->d, nlimbs * sizeof(mpi_limb_t), info ); @@ -226,8 +178,6 @@ mpi_debug_free( MPI a, const char *info ) mpi_free( MPI a ) #endif { - unused_obj_t u; - if( !a ) return; if( DBG_MEMORY ) @@ -238,13 +188,7 @@ mpi_free( MPI a ) mpi_free_limb_space(a->d); #endif - if( (u=unused_objs) ) - unused_objs = unused_objs->next; - else - u = m_alloc( sizeof *u ); - u->u.mpi = a; - u->next = unused_mpis; - unused_mpis = u; + m_free(a); } @@ -264,12 +208,15 @@ mpi_copy( MPI a ) if( a ) { #ifdef M_DEBUG - b = mpi_debug_alloc( a->nlimbs, info ); + b = a->secure? mpi_debug_alloc_secure( a->nlimbs, info ) + : mpi_debug_alloc( a->nlimbs, info ); #else - b = mpi_alloc( a->nlimbs ); + b = a->secure? mpi_alloc_secure( a->nlimbs ) + : mpi_alloc( a->nlimbs ); #endif b->nlimbs = a->nlimbs; b->sign = a->sign; + b->secure = a->secure; for(i=0; i < b->nlimbs; i++ ) b->d[i] = a->d[i]; } diff --git a/mpi/sysdep.h b/mpi/sysdep.h new file mode 100644 index 000000000..87cb7bf19 --- /dev/null +++ b/mpi/sysdep.h @@ -0,0 +1,13 @@ +#ifdef C_UNDERSCORE + +#if __STDC__ +#define C_SYMBOL_NAME(name) _##name +#else +#define C_SYMBOL_NAME(name) _/**/name +#endif + +#else /* C_UNDERSCORE */ + +#define C_SYMBOL_NAME(name) name + +#endif /* C_UNDERSCORE */