summaryrefslogtreecommitdiffabout
path: root/pwmanager/libcrypt/mpi/mpiutil.c
Unidiff
Diffstat (limited to 'pwmanager/libcrypt/mpi/mpiutil.c') (more/less context) (show whitespace changes)
-rw-r--r--pwmanager/libcrypt/mpi/mpiutil.c431
1 files changed, 431 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/mpi/mpiutil.c b/pwmanager/libcrypt/mpi/mpiutil.c
new file mode 100644
index 0000000..2a0bafa
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpiutil.c
@@ -0,0 +1,431 @@
1/* mpiutil.ac - Utility functions for MPI
2 * Copyright (C) 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <assert.h>
26
27#include "g10lib.h"
28#include "mpi-internal.h"
29#include "memory.h"
30
31/****************
32 * Note: It was a bad idea to use the number of limbs to allocate
33 * because on a alpha the limbs are large but we normally need
34 * integers of n bits - So we should chnage this to bits (or bytes).
35 *
36 * But mpi_alloc is used in a lot of places :-)
37 */
38gcry_mpi_t
39_gcry_mpi_alloc( unsigned nlimbs )
40{
41 gcry_mpi_t a;
42
43 a = gcry_xmalloc( sizeof *a );
44 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
45 a->alloced = nlimbs;
46 a->nlimbs = 0;
47 a->sign = 0;
48 a->flags = 0;
49 return a;
50}
51
52void
53_gcry_mpi_m_check( gcry_mpi_t a )
54{
55 _gcry_check_heap(a);
56 _gcry_check_heap(a->d);
57}
58
59gcry_mpi_t
60_gcry_mpi_alloc_secure( unsigned nlimbs )
61{
62 gcry_mpi_t a;
63
64 a = gcry_xmalloc( sizeof *a );
65 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
66 a->alloced = nlimbs;
67 a->flags = 1;
68 a->nlimbs = 0;
69 a->sign = 0;
70 return a;
71}
72
73
74
75mpi_ptr_t
76_gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
77{
78 size_t len = nlimbs * sizeof(mpi_limb_t);
79 mpi_ptr_t p = NULL;
80
81 if (!nlimbs)
82 {
83 p = secure? gcry_xmalloc_secure( 1 ) : gcry_xmalloc( 1 );
84 *p = 0;
85 }
86 else
87 p = secure? gcry_xmalloc_secure( len ) : gcry_xmalloc( len );
88
89 return p;
90}
91
92void
93_gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
94{
95 if (a)
96 {
97 size_t len = nlimbs * sizeof(mpi_limb_t);
98
99 /* If we have information on the number of allocated limbs, we
100 better wipe that space out. This is a failsafe feature if
101 secure memory has been disabled or was not properly
102 implemented in user provided allocation functions. */
103 if (len)
104 wipememory (a, len);
105 gcry_free(a);
106 }
107}
108
109
110void
111_gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
112{
113 _gcry_mpi_free_limb_space (a->d, a->alloced);
114 a->d = ap;
115 a->alloced = nlimbs;
116}
117
118
119
120/****************
121 * Resize the array of A to NLIMBS. the additional space is cleared
122 * (set to 0) [done by gcry_realloc()]
123 */
124void
125_gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
126{
127 if (nlimbs <= a->alloced)
128 return; /* no need to do it */
129
130 if (a->d)
131 a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
132 else
133 {
134 if (a->flags & 1)
135 /* Secure memory is wanted. */
136 a->d = gcry_xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
137 else
138 /* Standard memory. */
139 a->d = gcry_xcalloc (nlimbs , sizeof (mpi_limb_t));
140 }
141 a->alloced = nlimbs;
142}
143
144void
145_gcry_mpi_clear( gcry_mpi_t a )
146{
147 a->nlimbs = 0;
148 a->flags = 0;
149}
150
151
152void
153_gcry_mpi_free( gcry_mpi_t a )
154{
155 if (!a )
156 return;
157 if ((a->flags & 4))
158 gcry_free( a->d );
159 else
160 {
161 _gcry_mpi_free_limb_space(a->d, a->alloced);
162 }
163 if ((a->flags & ~7))
164 log_bug("invalid flag value in mpi\n");
165 gcry_free(a);
166}
167
168static void
169mpi_set_secure( gcry_mpi_t a )
170{
171 mpi_ptr_t ap, bp;
172
173 if ( (a->flags & 1) )
174 return;
175 a->flags |= 1;
176 ap = a->d;
177 if (!a->nlimbs)
178 {
179 assert(!ap);
180 return;
181 }
182 bp = mpi_alloc_limb_space (a->nlimbs, 1);
183 MPN_COPY( bp, ap, a->nlimbs );
184 a->d = bp;
185 _gcry_mpi_free_limb_space (ap, a->alloced);
186}
187
188
189gcry_mpi_t
190gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits )
191{
192 if (!a)
193 a = mpi_alloc(0);
194
195 if( a->flags & 4 )
196 gcry_free( a->d );
197 else
198 _gcry_mpi_free_limb_space (a->d, a->alloced);
199
200 a->d = p;
201 a->alloced = 0;
202 a->nlimbs = 0;
203 a->sign = nbits;
204 a->flags = 4;
205 return a;
206}
207
208
209void *
210gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits )
211{
212 if( !(a->flags & 4) )
213 log_bug("mpi_get_opaque on normal mpi\n");
214 if( nbits )
215 *nbits = a->sign;
216 return a->d;
217}
218
219
220/****************
221 * Note: This copy function should not interpret the MPI
222 * but copy it transparently.
223 */
224gcry_mpi_t
225_gcry_mpi_copy( gcry_mpi_t a )
226{
227 int i;
228 gcry_mpi_t b;
229
230 if( a && (a->flags & 4) ) {
231 void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 )
232 : gcry_xmalloc( (a->sign+7)/8 );
233 memcpy( p, a->d, (a->sign+7)/8 );
234 b = gcry_mpi_set_opaque( NULL, p, a->sign );
235 }
236 else if( a ) {
237 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
238 : mpi_alloc( a->nlimbs );
239 b->nlimbs = a->nlimbs;
240 b->sign = a->sign;
241 b->flags = a->flags;
242 for(i=0; i < b->nlimbs; i++ )
243 b->d[i] = a->d[i];
244 }
245 else
246 b = NULL;
247 return b;
248}
249
250
251/****************
252 * This function allocates an MPI which is optimized to hold
253 * a value as large as the one given in the argument and allocates it
254 * with the same flags as A.
255 */
256gcry_mpi_t
257_gcry_mpi_alloc_like( gcry_mpi_t a )
258{
259 gcry_mpi_t b;
260
261 if( a && (a->flags & 4) ) {
262 int n = (a->sign+7)/8;
263 void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n )
264 : gcry_malloc( n );
265 memcpy( p, a->d, n );
266 b = gcry_mpi_set_opaque( NULL, p, a->sign );
267 }
268 else if( a ) {
269 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
270 : mpi_alloc( a->nlimbs );
271 b->nlimbs = 0;
272 b->sign = 0;
273 b->flags = a->flags;
274 }
275 else
276 b = NULL;
277 return b;
278}
279
280
281void
282_gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u)
283{
284 mpi_ptr_t wp, up;
285 mpi_size_t usize = u->nlimbs;
286 int usign = u->sign;
287
288 RESIZE_IF_NEEDED(w, usize);
289 wp = w->d;
290 up = u->d;
291 MPN_COPY( wp, up, usize );
292 w->nlimbs = usize;
293 w->flags = u->flags;
294 w->sign = usign;
295}
296
297
298void
299_gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u)
300{
301 RESIZE_IF_NEEDED(w, 1);
302 w->d[0] = u;
303 w->nlimbs = u? 1:0;
304 w->sign = 0;
305 w->flags = 0;
306}
307
308
309gcry_mpi_t
310_gcry_mpi_alloc_set_ui( unsigned long u)
311{
312 gcry_mpi_t w = mpi_alloc(1);
313 w->d[0] = u;
314 w->nlimbs = u? 1:0;
315 w->sign = 0;
316 return w;
317}
318
319
320void
321_gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
322{
323 struct gcry_mpi tmp;
324
325 tmp = *a; *a = *b; *b = tmp;
326}
327
328void
329gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
330{
331 _gcry_mpi_swap (a, b);
332}
333
334
335gcry_mpi_t
336gcry_mpi_new( unsigned int nbits )
337{
338 return _gcry_mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB );
339}
340
341
342gcry_mpi_t
343gcry_mpi_snew( unsigned int nbits )
344{
345 return _gcry_mpi_alloc_secure( (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB );
346}
347
348void
349gcry_mpi_release( gcry_mpi_t a )
350{
351 _gcry_mpi_free( a );
352}
353
354gcry_mpi_t
355gcry_mpi_copy( const gcry_mpi_t a )
356{
357 return _gcry_mpi_copy( (gcry_mpi_t)a );
358}
359
360gcry_mpi_t
361gcry_mpi_set( gcry_mpi_t w, const gcry_mpi_t u )
362{
363 if( !w )
364 w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
365 _gcry_mpi_set( w, (gcry_mpi_t)u );
366 return w;
367}
368
369gcry_mpi_t
370gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u )
371{
372 if( !w )
373 w = _gcry_mpi_alloc(1);
374 _gcry_mpi_set_ui( w, u );
375 return w;
376}
377
378
379void
380gcry_mpi_randomize( gcry_mpi_t w,
381 unsigned int nbits, enum gcry_random_level level )
382{
383 char *p;
384 size_t nbytes = (nbits+7)/8;
385
386 if (level == GCRY_WEAK_RANDOM)
387 {
388 p = mpi_is_secure(w) ? gcry_xmalloc (nbytes)
389 : gcry_xmalloc_secure (nbytes);
390 gcry_create_nonce (p, nbytes);
391 }
392 else
393 {
394 p = mpi_is_secure(w) ? gcry_random_bytes (nbytes, level)
395 : gcry_random_bytes_secure (nbytes, level);
396 }
397 _gcry_mpi_set_buffer( w, p, nbytes, 0 );
398 gcry_free (p);
399}
400
401
402void
403gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
404{
405 switch( flag ) {
406 case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
407 case GCRYMPI_FLAG_OPAQUE:
408 default: log_bug("invalid flag value\n");
409 }
410}
411
412void
413gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
414{
415 switch( flag ) {
416 case GCRYMPI_FLAG_SECURE:
417 case GCRYMPI_FLAG_OPAQUE:
418 default: log_bug("invalid flag value\n");
419 }
420}
421
422int
423gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
424{
425 switch( flag ) {
426 case GCRYMPI_FLAG_SECURE: return (a->flags & 1);
427 case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4);
428 default: log_bug("invalid flag value\n");
429 }
430}
431