File Index
Files and directories
Sign in
FILE

mpi-mul.c

File preview with syntax highlighting.

linux-6.19.14/lib/crypto/mpi/mpi-mul.c C
  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 <linux/export.h>
 15
 16#include "mpi-internal.h"
 17
 18int mpi_mul(MPI w, MPI u, MPI v)
 19{
 20	mpi_size_t usize, vsize, wsize;
 21	mpi_ptr_t up, vp, wp;
 22	mpi_limb_t cy;
 23	int usign, vsign, sign_product;
 24	int assign_wp = 0;
 25	mpi_ptr_t tmp_limb = NULL;
 26	int err = 0;
 27
 28	if (u->nlimbs < v->nlimbs) {
 29		/* Swap U and V. */
 30		usize = v->nlimbs;
 31		usign = v->sign;
 32		up    = v->d;
 33		vsize = u->nlimbs;
 34		vsign = u->sign;
 35		vp    = u->d;
 36	} else {
 37		usize = u->nlimbs;
 38		usign = u->sign;
 39		up    = u->d;
 40		vsize = v->nlimbs;
 41		vsign = v->sign;
 42		vp    = v->d;
 43	}
 44	sign_product = usign ^ vsign;
 45	wp = w->d;
 46
 47	/* Ensure W has space enough to store the result.  */
 48	wsize = usize + vsize;
 49	if (w->alloced < wsize) {
 50		if (wp == up || wp == vp) {
 51			wp = mpi_alloc_limb_space(wsize);
 52			if (!wp)
 53				return -ENOMEM;
 54			assign_wp = 1;
 55		} else {
 56			err = mpi_resize(w, wsize);
 57			if (err)
 58				return err;
 59			wp = w->d;
 60		}
 61	} else { /* Make U and V not overlap with W.	*/
 62		if (wp == up) {
 63			/* W and U are identical.  Allocate temporary space for U. */
 64			up = tmp_limb = mpi_alloc_limb_space(usize);
 65			if (!up)
 66				return -ENOMEM;
 67			/* Is V identical too?  Keep it identical with U.  */
 68			if (wp == vp)
 69				vp = up;
 70			/* Copy to the temporary space.  */
 71			MPN_COPY(up, wp, usize);
 72		} else if (wp == vp) {
 73			/* W and V are identical.  Allocate temporary space for V. */
 74			vp = tmp_limb = mpi_alloc_limb_space(vsize);
 75			if (!vp)
 76				return -ENOMEM;
 77			/* Copy to the temporary space.  */
 78			MPN_COPY(vp, wp, vsize);
 79		}
 80	}
 81
 82	if (!vsize)
 83		wsize = 0;
 84	else {
 85		err = mpihelp_mul(wp, up, usize, vp, vsize, &cy);
 86		if (err) {
 87			if (assign_wp)
 88				mpi_free_limb_space(wp);
 89			goto free_tmp_limb;
 90		}
 91		wsize -= cy ? 0:1;
 92	}
 93
 94	if (assign_wp)
 95		mpi_assign_limb_space(w, wp, wsize);
 96	w->nlimbs = wsize;
 97	w->sign = sign_product;
 98
 99free_tmp_limb:
100	if (tmp_limb)
101		mpi_free_limb_space(tmp_limb);
102	return err;
103}
104EXPORT_SYMBOL_GPL(mpi_mul);
105
106int mpi_mulm(MPI w, MPI u, MPI v, MPI m)
107{
108	return mpi_mul(w, u, v) ?:
109	       mpi_tdiv_r(w, w, m);
110}
111EXPORT_SYMBOL_GPL(mpi_mulm);
~/ Read-only file preview.