1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "mpi-internal.h"
22
23
24
25
26
27
28
29
30MPI mpi_alloc(unsigned nlimbs)
31{
32 MPI a;
33
34 a = kmalloc(sizeof *a, GFP_KERNEL);
35 if (!a)
36 return a;
37
38 if (nlimbs) {
39 a->d = mpi_alloc_limb_space(nlimbs);
40 if (!a->d) {
41 kfree(a);
42 return NULL;
43 }
44 } else {
45 a->d = NULL;
46 }
47
48 a->alloced = nlimbs;
49 a->nlimbs = 0;
50 a->sign = 0;
51 a->flags = 0;
52 a->nbits = 0;
53 return a;
54}
55EXPORT_SYMBOL_GPL(mpi_alloc);
56
57mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs)
58{
59 size_t len = nlimbs * sizeof(mpi_limb_t);
60
61 if (!len)
62 return NULL;
63
64 return kmalloc(len, GFP_KERNEL);
65}
66
67void mpi_free_limb_space(mpi_ptr_t a)
68{
69 if (!a)
70 return;
71
72 kfree(a);
73}
74
75void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs)
76{
77 mpi_free_limb_space(a->d);
78 a->d = ap;
79 a->alloced = nlimbs;
80}
81
82
83
84
85
86int mpi_resize(MPI a, unsigned nlimbs)
87{
88 void *p;
89
90 if (nlimbs <= a->alloced)
91 return 0;
92
93 if (a->d) {
94 p = kmalloc(nlimbs * sizeof(mpi_limb_t), GFP_KERNEL);
95 if (!p)
96 return -ENOMEM;
97 memcpy(p, a->d, a->alloced * sizeof(mpi_limb_t));
98 kfree(a->d);
99 a->d = p;
100 } else {
101 a->d = kzalloc(nlimbs * sizeof(mpi_limb_t), GFP_KERNEL);
102 if (!a->d)
103 return -ENOMEM;
104 }
105 a->alloced = nlimbs;
106 return 0;
107}
108
109void mpi_clear(MPI a)
110{
111 a->nlimbs = 0;
112 a->nbits = 0;
113 a->flags = 0;
114}
115
116void mpi_free(MPI a)
117{
118 if (!a)
119 return;
120
121 if (a->flags & 4)
122 kfree(a->d);
123 else
124 mpi_free_limb_space(a->d);
125
126 if (a->flags & ~7)
127 pr_info("invalid flag value in mpi\n");
128 kfree(a);
129}
130EXPORT_SYMBOL_GPL(mpi_free);
131
132
133
134
135
136int mpi_copy(MPI *copied, const MPI a)
137{
138 size_t i;
139 MPI b;
140
141 *copied = NULL;
142
143 if (a) {
144 b = mpi_alloc(a->nlimbs);
145 if (!b)
146 return -ENOMEM;
147
148 b->nlimbs = a->nlimbs;
149 b->sign = a->sign;
150 b->flags = a->flags;
151 b->nbits = a->nbits;
152
153 for (i = 0; i < b->nlimbs; i++)
154 b->d[i] = a->d[i];
155
156 *copied = b;
157 }
158
159 return 0;
160}
161
162int mpi_set(MPI w, const MPI u)
163{
164 mpi_ptr_t wp, up;
165 mpi_size_t usize = u->nlimbs;
166 int usign = u->sign;
167
168 if (RESIZE_IF_NEEDED(w, (size_t) usize) < 0)
169 return -ENOMEM;
170
171 wp = w->d;
172 up = u->d;
173 MPN_COPY(wp, up, usize);
174 w->nlimbs = usize;
175 w->nbits = u->nbits;
176 w->flags = u->flags;
177 w->sign = usign;
178 return 0;
179}
180
181int mpi_set_ui(MPI w, unsigned long u)
182{
183 if (RESIZE_IF_NEEDED(w, 1) < 0)
184 return -ENOMEM;
185 w->d[0] = u;
186 w->nlimbs = u ? 1 : 0;
187 w->sign = 0;
188 w->nbits = 0;
189 w->flags = 0;
190 return 0;
191}
192
193MPI mpi_alloc_set_ui(unsigned long u)
194{
195 MPI w = mpi_alloc(1);
196 if (!w)
197 return w;
198 w->d[0] = u;
199 w->nlimbs = u ? 1 : 0;
200 w->sign = 0;
201 return w;
202}
203
204void mpi_swap(MPI a, MPI b)
205{
206 struct gcry_mpi tmp;
207
208 tmp = *a;
209 *a = *b;
210 *b = tmp;
211}
212