Release 1.8.0
[libgcrypt.git] / mpi / mpi-mul.c
index bfca5d0..4f4d709 100644 (file)
@@ -1,21 +1,20 @@
 /* mpi-mul.c  -  MPI functions
- *     Copyright (C) 1998 Free Software Foundation, Inc.
- *     Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+ * Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
  *
- * This file is part of GNUPG.
+ * This file is part of Libgcrypt.
  *
- * GNUPG 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.
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
  *
- * GNUPG is distributed in the hope that it will be useful,
+ * Libgcrypt 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.
+ * GNU Lesser 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
+ * You should have received a copy of the GNU Lesser 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.
@@ -23,8 +22,6 @@
  *      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 <config.h>
@@ -34,7 +31,7 @@
 
 
 void
-mpi_mul_ui( MPI prod, MPI mult, unsigned long small_mult )
+_gcry_mpi_mul_ui (gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult)
 {
     mpi_size_t size, prod_size;
     mpi_ptr_t  prod_ptr;
@@ -55,7 +52,7 @@ mpi_mul_ui( MPI prod, MPI mult, unsigned long small_mult )
        mpi_resize( prod, prod_size );
     prod_ptr = prod->d;
 
-    cy = mpihelp_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
+    cy = _gcry_mpih_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
     if( cy )
        prod_ptr[size++] = cy;
     prod->nlimbs = size;
@@ -64,7 +61,7 @@ mpi_mul_ui( MPI prod, MPI mult, unsigned long small_mult )
 
 
 void
-mpi_mul_2exp( MPI w, MPI u, unsigned long cnt)
+_gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
 {
     mpi_size_t usize, wsize, limb_cnt;
     mpi_ptr_t wp;
@@ -90,7 +87,7 @@ mpi_mul_2exp( MPI w, MPI u, unsigned long cnt)
 
     cnt %= BITS_PER_MPI_LIMB;
     if( cnt ) {
-       wlimb = mpihelp_lshift( wp + limb_cnt, u->d, usize, cnt );
+       wlimb = _gcry_mpih_lshift( wp + limb_cnt, u->d, usize, cnt );
        if( wlimb ) {
            wp[wsize] = wlimb;
            wsize++;
@@ -109,9 +106,8 @@ mpi_mul_2exp( MPI w, MPI u, unsigned long cnt)
 }
 
 
-
 void
-mpi_mul( MPI w, MPI u, MPI v)
+_gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
 {
     mpi_size_t usize, vsize, wsize;
     mpi_ptr_t up, vp, wp;
@@ -119,25 +115,26 @@ mpi_mul( MPI w, MPI u, MPI v)
     int usign, vsign, usecure, vsecure, sign_product;
     int assign_wp=0;
     mpi_ptr_t tmp_limb=NULL;
+    unsigned int tmp_limb_nlimbs = 0;
 
     if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
        usize = v->nlimbs;
        usign = v->sign;
-       usecure = v->secure;
+       usecure = mpi_is_secure(v);
        up    = v->d;
        vsize = u->nlimbs;
        vsign = u->sign;
-       vsecure = u->secure;
+       vsecure = mpi_is_secure(u);
        vp    = u->d;
     }
     else {
        usize = u->nlimbs;
        usign = u->sign;
-       usecure = u->secure;
+       usecure = mpi_is_secure(u);
        up    = u->d;
        vsize = v->nlimbs;
        vsign = v->sign;
-       vsecure = v->secure;
+       vsecure = mpi_is_secure(v);
        vp    = v->d;
     }
     sign_product = usign ^ vsign;
@@ -145,9 +142,17 @@ mpi_mul( MPI w, MPI u, MPI v)
 
     /* Ensure W has space enough to store the result.  */
     wsize = usize + vsize;
-    if( w->alloced < wsize ) {
+    if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
+        /* w is not allocated in secure space but u or v is.  To make sure
+         * that no temporray results are stored in w, we temporary use
+         * a newly allocated limb space for w */
+        wp = mpi_alloc_limb_space( wsize, 1 );
+        assign_wp = 2; /* mark it as 2 so that we can later copy it back to
+                        * mormal memory */
+    }
+    else if( w->alloced < wsize ) {
        if( wp == up || wp == vp ) {
-           wp = mpi_alloc_limb_space( wsize, w->secure );
+           wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) );
            assign_wp = 1;
        }
        else {
@@ -158,6 +163,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.  */
+            tmp_limb_nlimbs = usize;
            up = tmp_limb = mpi_alloc_limb_space( usize, usecure  );
            /* Is V identical too?  Keep it identical with U.  */
            if( wp == vp )
@@ -167,6 +173,7 @@ mpi_mul( MPI w, MPI u, MPI v)
        }
        else if( wp == vp ) {
            /* W and V are identical.  Allocate temporary space for V.  */
+            tmp_limb_nlimbs = vsize;
            vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure );
            /* Copy to the temporary space.  */
            MPN_COPY( vp, wp, vsize );
@@ -176,23 +183,30 @@ mpi_mul( MPI w, MPI u, MPI v)
     if( !vsize )
        wsize = 0;
     else {
-       cy = mpihelp_mul( wp, up, usize, vp, vsize );
+       cy = _gcry_mpih_mul( wp, up, usize, vp, vsize );
        wsize -= cy? 0:1;
     }
 
-    if( assign_wp )
-       mpi_assign_limb_space( w, wp, wsize );
+    if( assign_wp ) {
+        if (assign_wp == 2) {
+            /* copy the temp wp from secure memory back to normal memory */
+           mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0);
+           MPN_COPY (tmp_wp, wp, wsize);
+            _gcry_mpi_free_limb_space (wp, 0);
+            wp = tmp_wp;
+        }
+       _gcry_mpi_assign_limb_space( w, wp, wsize );
+    }
     w->nlimbs = wsize;
     w->sign = sign_product;
     if( tmp_limb )
-       mpi_free_limb_space( tmp_limb );
+       _gcry_mpi_free_limb_space (tmp_limb, tmp_limb_nlimbs);
 }
 
 
 void
-mpi_mulm( MPI w, MPI u, MPI v, MPI m)
+_gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
 {
-    mpi_mul(w, u, v);
-    mpi_fdiv_r( w, w, m );
+  mpi_mul (w, u, v);
+  _gcry_mpi_tdiv_r (w, w, m);
 }
-