Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/lib/crypto/mpi/mpi-mul.c
29278 views
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
18
int 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
99
free_tmp_limb:
100
if (tmp_limb)
101
mpi_free_limb_space(tmp_limb);
102
return err;
103
}
104
EXPORT_SYMBOL_GPL(mpi_mul);
105
106
int 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
}
111
EXPORT_SYMBOL_GPL(mpi_mulm);
112
113