author | zautrix <zautrix> | 2004-10-19 20:16:14 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-10-19 20:16:14 (UTC) |
commit | eca49bb06a71980ef61d078904573f25890fc7f2 (patch) (unidiff) | |
tree | c5338e3b12430248979a9ac2c1c7e6646ea9ecdf /pwmanager/libcrypt/mpi/mpiutil.c | |
parent | 53cc32b6e7b1f672bf91b2baf2df6c1e8baf3e0a (diff) | |
download | kdepimpi-eca49bb06a71980ef61d078904573f25890fc7f2.zip kdepimpi-eca49bb06a71980ef61d078904573f25890fc7f2.tar.gz kdepimpi-eca49bb06a71980ef61d078904573f25890fc7f2.tar.bz2 |
Initial revision
Diffstat (limited to 'pwmanager/libcrypt/mpi/mpiutil.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | pwmanager/libcrypt/mpi/mpiutil.c | 431 |
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 | */ | ||
38 | gcry_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 | |||
52 | void | ||
53 | _gcry_mpi_m_check( gcry_mpi_t a ) | ||
54 | { | ||
55 | _gcry_check_heap(a); | ||
56 | _gcry_check_heap(a->d); | ||
57 | } | ||
58 | |||
59 | gcry_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 | |||
75 | mpi_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 | |||
92 | void | ||
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 | |||
110 | void | ||
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 | */ | ||
124 | void | ||
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 | |||
144 | void | ||
145 | _gcry_mpi_clear( gcry_mpi_t a ) | ||
146 | { | ||
147 | a->nlimbs = 0; | ||
148 | a->flags = 0; | ||
149 | } | ||
150 | |||
151 | |||
152 | void | ||
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 | |||
168 | static void | ||
169 | mpi_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 | |||
189 | gcry_mpi_t | ||
190 | gcry_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 | |||
209 | void * | ||
210 | gcry_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 | */ | ||
224 | gcry_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 | */ | ||
256 | gcry_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 | |||
281 | void | ||
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 | |||
298 | void | ||
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 | |||
309 | gcry_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 | |||
320 | void | ||
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 | |||
328 | void | ||
329 | gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b) | ||
330 | { | ||
331 | _gcry_mpi_swap (a, b); | ||
332 | } | ||
333 | |||
334 | |||
335 | gcry_mpi_t | ||
336 | gcry_mpi_new( unsigned int nbits ) | ||
337 | { | ||
338 | return _gcry_mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB ); | ||
339 | } | ||
340 | |||
341 | |||
342 | gcry_mpi_t | ||
343 | gcry_mpi_snew( unsigned int nbits ) | ||
344 | { | ||
345 | return _gcry_mpi_alloc_secure( (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB ); | ||
346 | } | ||
347 | |||
348 | void | ||
349 | gcry_mpi_release( gcry_mpi_t a ) | ||
350 | { | ||
351 | _gcry_mpi_free( a ); | ||
352 | } | ||
353 | |||
354 | gcry_mpi_t | ||
355 | gcry_mpi_copy( const gcry_mpi_t a ) | ||
356 | { | ||
357 | return _gcry_mpi_copy( (gcry_mpi_t)a ); | ||
358 | } | ||
359 | |||
360 | gcry_mpi_t | ||
361 | gcry_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 | |||
369 | gcry_mpi_t | ||
370 | gcry_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 | |||
379 | void | ||
380 | gcry_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 | |||
402 | void | ||
403 | gcry_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 | |||
412 | void | ||
413 | gcry_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 | |||
422 | int | ||
423 | gcry_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 | |||