cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mpi-mul.c (2198B)


      1/* mpi-mul.c  -  MPI functions
      2 * Copyright (C) 1994, 1996, 1998, 2001, 2002,
      3 *               2003 Free Software Foundation, Inc.
      4 *
      5 * This file is part of Libgcrypt.
      6 *
      7 * Note: This code is heavily based on the GNU MP Library.
      8 *	 Actually it's the same code with only minor changes in the
      9 *	 way the data is stored; this is to support the abstraction
     10 *	 of an optional secure memory allocation which may be used
     11 *	 to avoid revealing of sensitive data due to paging etc.
     12 */
     13
     14#include "mpi-internal.h"
     15
     16void mpi_mul(MPI w, MPI u, MPI v)
     17{
     18	mpi_size_t usize, vsize, wsize;
     19	mpi_ptr_t up, vp, wp;
     20	mpi_limb_t cy;
     21	int usign, vsign, sign_product;
     22	int assign_wp = 0;
     23	mpi_ptr_t tmp_limb = NULL;
     24
     25	if (u->nlimbs < v->nlimbs) {
     26		/* Swap U and V. */
     27		usize = v->nlimbs;
     28		usign = v->sign;
     29		up    = v->d;
     30		vsize = u->nlimbs;
     31		vsign = u->sign;
     32		vp    = u->d;
     33	} else {
     34		usize = u->nlimbs;
     35		usign = u->sign;
     36		up    = u->d;
     37		vsize = v->nlimbs;
     38		vsign = v->sign;
     39		vp    = v->d;
     40	}
     41	sign_product = usign ^ vsign;
     42	wp = w->d;
     43
     44	/* Ensure W has space enough to store the result.  */
     45	wsize = usize + vsize;
     46	if (w->alloced < wsize) {
     47		if (wp == up || wp == vp) {
     48			wp = mpi_alloc_limb_space(wsize);
     49			assign_wp = 1;
     50		} else {
     51			mpi_resize(w, wsize);
     52			wp = w->d;
     53		}
     54	} else { /* Make U and V not overlap with W.	*/
     55		if (wp == up) {
     56			/* W and U are identical.  Allocate temporary space for U. */
     57			up = tmp_limb = mpi_alloc_limb_space(usize);
     58			/* Is V identical too?  Keep it identical with U.  */
     59			if (wp == vp)
     60				vp = up;
     61			/* Copy to the temporary space.  */
     62			MPN_COPY(up, wp, usize);
     63		} else if (wp == vp) {
     64			/* W and V are identical.  Allocate temporary space for V. */
     65			vp = tmp_limb = mpi_alloc_limb_space(vsize);
     66			/* Copy to the temporary space.  */
     67			MPN_COPY(vp, wp, vsize);
     68		}
     69	}
     70
     71	if (!vsize)
     72		wsize = 0;
     73	else {
     74		mpihelp_mul(wp, up, usize, vp, vsize, &cy);
     75		wsize -= cy ? 0:1;
     76	}
     77
     78	if (assign_wp)
     79		mpi_assign_limb_space(w, wp, wsize);
     80	w->nlimbs = wsize;
     81	w->sign = sign_product;
     82	if (tmp_limb)
     83		mpi_free_limb_space(tmp_limb);
     84}
     85
     86void mpi_mulm(MPI w, MPI u, MPI v, MPI m)
     87{
     88	mpi_mul(w, u, v);
     89	mpi_tdiv_r(w, w, m);
     90}
     91EXPORT_SYMBOL_GPL(mpi_mulm);