Line data Source code
1 : /* mpiutil.ac - Utility functions for MPI
2 : * Copyright (C) 1998, 2000, 2001, 2002, 2003,
3 : * 2007 Free Software Foundation, Inc.
4 : * Copyright (C) 2013 g10 Code GmbH
5 : *
6 : * This file is part of Libgcrypt.
7 : *
8 : * Libgcrypt is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU Lesser General Public License as
10 : * published by the Free Software Foundation; either version 2.1 of
11 : * the License, or (at your option) any later version.
12 : *
13 : * Libgcrypt is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU Lesser General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU Lesser General Public
19 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include <config.h>
23 : #include <stdio.h>
24 : #include <stdlib.h>
25 : #include <string.h>
26 :
27 : #include "g10lib.h"
28 : #include "mpi-internal.h"
29 : #include "mod-source-info.h"
30 :
31 : /* Constants allocated right away at startup. */
32 : static gcry_mpi_t constants[MPI_NUMBER_OF_CONSTANTS];
33 :
34 :
35 :
36 : const char *
37 1 : _gcry_mpi_get_hw_config (void)
38 : {
39 1 : return mod_source_info + 1;
40 : }
41 :
42 :
43 : /* Initialize the MPI subsystem. This is called early and allows to
44 : do some initialization without taking care of threading issues. */
45 : gcry_err_code_t
46 31 : _gcry_mpi_init (void)
47 : {
48 : int idx;
49 : unsigned long value;
50 :
51 217 : for (idx=0; idx < MPI_NUMBER_OF_CONSTANTS; idx++)
52 : {
53 186 : switch (idx)
54 : {
55 31 : case MPI_C_ZERO: value = 0; break;
56 31 : case MPI_C_ONE: value = 1; break;
57 31 : case MPI_C_TWO: value = 2; break;
58 31 : case MPI_C_THREE: value = 3; break;
59 31 : case MPI_C_FOUR: value = 4; break;
60 31 : case MPI_C_EIGHT: value = 8; break;
61 0 : default: log_bug ("invalid mpi_const selector %d\n", idx);
62 : }
63 186 : constants[idx] = mpi_alloc_set_ui (value);
64 186 : constants[idx]->flags = (16|32);
65 : }
66 :
67 31 : return 0;
68 : }
69 :
70 :
71 : /****************
72 : * Note: It was a bad idea to use the number of limbs to allocate
73 : * because on a alpha the limbs are large but we normally need
74 : * integers of n bits - So we should change this to bits (or bytes).
75 : *
76 : * But mpi_alloc is used in a lot of places :-(. New code
77 : * should use mpi_new.
78 : */
79 : gcry_mpi_t
80 15106767 : _gcry_mpi_alloc( unsigned nlimbs )
81 : {
82 : gcry_mpi_t a;
83 :
84 15106767 : a = xmalloc( sizeof *a );
85 15106767 : a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
86 15106767 : a->alloced = nlimbs;
87 15106767 : a->nlimbs = 0;
88 15106767 : a->sign = 0;
89 15106767 : a->flags = 0;
90 15106767 : return a;
91 : }
92 :
93 : void
94 0 : _gcry_mpi_m_check( gcry_mpi_t a )
95 : {
96 0 : _gcry_check_heap(a);
97 0 : _gcry_check_heap(a->d);
98 0 : }
99 :
100 : gcry_mpi_t
101 291148 : _gcry_mpi_alloc_secure( unsigned nlimbs )
102 : {
103 : gcry_mpi_t a;
104 :
105 291148 : a = xmalloc( sizeof *a );
106 291148 : a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
107 291148 : a->alloced = nlimbs;
108 291148 : a->flags = 1;
109 291148 : a->nlimbs = 0;
110 291148 : a->sign = 0;
111 291148 : return a;
112 : }
113 :
114 :
115 :
116 : mpi_ptr_t
117 59210342 : _gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
118 : {
119 : mpi_ptr_t p;
120 : size_t len;
121 :
122 59210342 : len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
123 59210342 : p = secure ? xmalloc_secure (len) : xmalloc (len);
124 59210342 : if (! nlimbs)
125 8348 : *p = 0;
126 :
127 59210342 : return p;
128 : }
129 :
130 : void
131 59304183 : _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
132 : {
133 59304183 : if (a)
134 : {
135 59276790 : size_t len = nlimbs * sizeof(mpi_limb_t);
136 :
137 : /* If we have information on the number of allocated limbs, we
138 : better wipe that space out. This is a failsafe feature if
139 : secure memory has been disabled or was not properly
140 : implemented in user provided allocation functions. */
141 59276790 : if (len)
142 58331886 : wipememory (a, len);
143 59276790 : xfree(a);
144 : }
145 59304183 : }
146 :
147 :
148 : void
149 18505 : _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
150 : {
151 18505 : _gcry_mpi_free_limb_space (a->d, a->alloced);
152 18505 : a->d = ap;
153 18505 : a->alloced = nlimbs;
154 18505 : }
155 :
156 :
157 :
158 : /****************
159 : * Resize the array of A to NLIMBS. The additional space is cleared
160 : * (set to 0).
161 : */
162 : void
163 33126526 : _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
164 : {
165 : size_t i;
166 :
167 33126526 : if (nlimbs <= a->alloced)
168 : {
169 : /* We only need to clear the new space (this is a nop if the
170 : limb space is already of the correct size. */
171 92654412 : for (i=a->nlimbs; i < a->alloced; i++)
172 59772925 : a->d[i] = 0;
173 66008013 : return;
174 : }
175 :
176 : /* Actually resize the limb space. */
177 245039 : if (a->d)
178 : {
179 178206 : a->d = xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
180 776433 : for (i=a->alloced; i < nlimbs; i++)
181 598227 : a->d[i] = 0;
182 : }
183 : else
184 : {
185 66833 : if (a->flags & 1)
186 : /* Secure memory is wanted. */
187 1214 : a->d = xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
188 : else
189 : /* Standard memory. */
190 65619 : a->d = xcalloc (nlimbs , sizeof (mpi_limb_t));
191 : }
192 245039 : a->alloced = nlimbs;
193 : }
194 :
195 : void
196 3 : _gcry_mpi_clear( gcry_mpi_t a )
197 : {
198 3 : if (mpi_is_immutable (a))
199 : {
200 0 : mpi_immutable_failed ();
201 3 : return;
202 : }
203 3 : a->nlimbs = 0;
204 3 : a->flags = 0;
205 : }
206 :
207 :
208 : void
209 15423366 : _gcry_mpi_free( gcry_mpi_t a )
210 : {
211 15423366 : if (!a )
212 25835 : return;
213 15397531 : if ((a->flags & 32))
214 1 : return; /* Never release a constant. */
215 15397530 : if ((a->flags & 4))
216 7763 : xfree( a->d );
217 : else
218 : {
219 15389767 : _gcry_mpi_free_limb_space(a->d, a->alloced);
220 : }
221 : /* Check that the flags makes sense. We better allow for bit 1
222 : (value 2) for backward ABI compatibility. */
223 15397530 : if ((a->flags & ~(1|2|4|16
224 : |GCRYMPI_FLAG_USER1
225 : |GCRYMPI_FLAG_USER2
226 : |GCRYMPI_FLAG_USER3
227 : |GCRYMPI_FLAG_USER4)))
228 0 : log_bug("invalid flag value in mpi_free\n");
229 15397530 : xfree (a);
230 : }
231 :
232 :
233 : void
234 0 : _gcry_mpi_immutable_failed (void)
235 : {
236 0 : log_info ("Warning: trying to change an immutable MPI\n");
237 0 : }
238 :
239 :
240 : static void
241 0 : mpi_set_secure( gcry_mpi_t a )
242 : {
243 : mpi_ptr_t ap, bp;
244 :
245 0 : if ( (a->flags & 1) )
246 0 : return;
247 0 : a->flags |= 1;
248 0 : ap = a->d;
249 0 : if (!a->nlimbs)
250 : {
251 0 : gcry_assert (!ap);
252 0 : return;
253 : }
254 0 : bp = mpi_alloc_limb_space (a->nlimbs, 1);
255 0 : MPN_COPY( bp, ap, a->nlimbs );
256 0 : a->d = bp;
257 0 : _gcry_mpi_free_limb_space (ap, a->alloced);
258 : }
259 :
260 :
261 : gcry_mpi_t
262 7765 : _gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
263 : {
264 7765 : if (!a)
265 2251 : a = mpi_alloc(0);
266 :
267 7765 : if (mpi_is_immutable (a))
268 : {
269 0 : mpi_immutable_failed ();
270 0 : return a;
271 : }
272 :
273 7765 : if( a->flags & 4 )
274 2 : xfree (a->d);
275 : else
276 7763 : _gcry_mpi_free_limb_space (a->d, a->alloced);
277 :
278 7765 : a->d = p;
279 7765 : a->alloced = 0;
280 7765 : a->nlimbs = 0;
281 7765 : a->sign = nbits;
282 7765 : a->flags = 4 | (a->flags & (GCRYMPI_FLAG_USER1|GCRYMPI_FLAG_USER2
283 : |GCRYMPI_FLAG_USER3|GCRYMPI_FLAG_USER4));
284 7765 : if (_gcry_is_secure (a->d))
285 0 : a->flags |= 1;
286 7765 : return a;
287 : }
288 :
289 :
290 : gcry_mpi_t
291 2 : _gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits)
292 : {
293 : void *d;
294 : unsigned int n;
295 :
296 2 : n = (nbits+7)/8;
297 2 : d = _gcry_is_secure (p)? xtrymalloc_secure (n) : xtrymalloc (n);
298 2 : if (!d)
299 0 : return NULL;
300 2 : memcpy (d, p, n);
301 2 : return mpi_set_opaque (a, d, nbits);
302 : }
303 :
304 :
305 : void *
306 7688 : _gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
307 : {
308 7688 : if( !(a->flags & 4) )
309 0 : log_bug("mpi_get_opaque on normal mpi\n");
310 7688 : if( nbits )
311 7688 : *nbits = a->sign;
312 7688 : return a->d;
313 : }
314 :
315 :
316 : void *
317 1036 : _gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits)
318 : {
319 : const void *s;
320 : void *d;
321 : unsigned int n;
322 :
323 1036 : s = mpi_get_opaque (a, nbits);
324 1036 : if (!s && nbits)
325 0 : return NULL;
326 1036 : n = (*nbits+7)/8;
327 1036 : d = _gcry_is_secure (s)? xtrymalloc_secure (n) : xtrymalloc (n);
328 1036 : if (d)
329 1036 : memcpy (d, s, n);
330 1036 : return d;
331 : }
332 :
333 : /****************
334 : * Note: This copy function should not interpret the MPI
335 : * but copy it transparently.
336 : */
337 : gcry_mpi_t
338 15226075 : _gcry_mpi_copy (gcry_mpi_t a)
339 : {
340 : int i;
341 : gcry_mpi_t b;
342 :
343 15226075 : if( a && (a->flags & 4) ) {
344 0 : void *p = _gcry_is_secure(a->d)? xmalloc_secure ((a->sign+7)/8)
345 0 : : xmalloc ((a->sign+7)/8);
346 0 : if (a->d)
347 0 : memcpy( p, a->d, (a->sign+7)/8 );
348 0 : b = mpi_set_opaque( NULL, p, a->sign );
349 0 : b->flags &= ~(16|32); /* Reset the immutable and constant flags. */
350 : }
351 15226075 : else if( a ) {
352 30452118 : b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
353 15512232 : : mpi_alloc( a->nlimbs );
354 15226059 : b->nlimbs = a->nlimbs;
355 15226059 : b->sign = a->sign;
356 15226059 : b->flags = a->flags;
357 15226059 : b->flags &= ~(16|32); /* Reset the immutable and constant flags. */
358 91608096 : for(i=0; i < b->nlimbs; i++ )
359 76382037 : b->d[i] = a->d[i];
360 : }
361 : else
362 16 : b = NULL;
363 15226075 : return b;
364 : }
365 :
366 :
367 : /* Return true if A is negative. */
368 : int
369 70 : _gcry_mpi_is_neg (gcry_mpi_t a)
370 : {
371 70 : if (a->sign && _gcry_mpi_cmp_ui (a, 0))
372 33 : return 1;
373 : else
374 37 : return 0;
375 : }
376 :
377 :
378 : /* W = - U */
379 : void
380 2522428 : _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u)
381 : {
382 2522428 : if (w != u)
383 0 : mpi_set (w, u);
384 2522428 : else if (mpi_is_immutable (w))
385 : {
386 0 : mpi_immutable_failed ();
387 2522428 : return;
388 : }
389 :
390 2522428 : w->sign = !u->sign;
391 : }
392 :
393 :
394 : /* W = [W] */
395 : void
396 1 : _gcry_mpi_abs (gcry_mpi_t w)
397 : {
398 1 : if (mpi_is_immutable (w))
399 : {
400 0 : mpi_immutable_failed ();
401 1 : return;
402 : }
403 :
404 1 : w->sign = 0;
405 : }
406 :
407 :
408 : /****************
409 : * This function allocates an MPI which is optimized to hold
410 : * a value as large as the one given in the argument and allocates it
411 : * with the same flags as A.
412 : */
413 : gcry_mpi_t
414 34239 : _gcry_mpi_alloc_like( gcry_mpi_t a )
415 : {
416 : gcry_mpi_t b;
417 :
418 34239 : if( a && (a->flags & 4) ) {
419 0 : int n = (a->sign+7)/8;
420 0 : void *p = _gcry_is_secure(a->d)? xtrymalloc_secure (n)
421 0 : : xtrymalloc (n);
422 0 : memcpy( p, a->d, n );
423 0 : b = mpi_set_opaque( NULL, p, a->sign );
424 : }
425 34239 : else if( a ) {
426 68478 : b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
427 34505 : : mpi_alloc( a->nlimbs );
428 34239 : b->nlimbs = 0;
429 34239 : b->sign = 0;
430 34239 : b->flags = a->flags;
431 : }
432 : else
433 0 : b = NULL;
434 34239 : return b;
435 : }
436 :
437 :
438 : /* Set U into W and release U. If W is NULL only U will be released. */
439 : void
440 77 : _gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u)
441 : {
442 77 : if (w)
443 : {
444 77 : if (mpi_is_immutable (w))
445 : {
446 0 : mpi_immutable_failed ();
447 77 : return;
448 : }
449 77 : _gcry_mpi_assign_limb_space (w, u->d, u->alloced);
450 77 : w->nlimbs = u->nlimbs;
451 77 : w->sign = u->sign;
452 77 : w->flags = u->flags;
453 77 : u->alloced = 0;
454 77 : u->nlimbs = 0;
455 77 : u->d = NULL;
456 : }
457 77 : _gcry_mpi_free (u);
458 : }
459 :
460 :
461 : gcry_mpi_t
462 5551699 : _gcry_mpi_set (gcry_mpi_t w, gcry_mpi_t u)
463 : {
464 : mpi_ptr_t wp, up;
465 5551699 : mpi_size_t usize = u->nlimbs;
466 5551699 : int usign = u->sign;
467 :
468 5551699 : if (!w)
469 1 : w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
470 5551699 : if (mpi_is_immutable (w))
471 : {
472 0 : mpi_immutable_failed ();
473 0 : return w;
474 : }
475 5551699 : RESIZE_IF_NEEDED(w, usize);
476 5551699 : wp = w->d;
477 5551699 : up = u->d;
478 5551699 : MPN_COPY( wp, up, usize );
479 5551699 : w->nlimbs = usize;
480 5551699 : w->flags = u->flags;
481 5551699 : w->flags &= ~(16|32); /* Reset the immutable and constant flags. */
482 5551699 : w->sign = usign;
483 5551699 : return w;
484 : }
485 :
486 : gcry_mpi_t
487 14709575 : _gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u, unsigned long set)
488 : {
489 : mpi_size_t i;
490 14709575 : mpi_size_t nlimbs = u->alloced;
491 14709575 : mpi_limb_t mask = ((mpi_limb_t)0) - !!set;
492 : mpi_limb_t x;
493 :
494 14709575 : if (w->alloced != u->alloced)
495 0 : log_bug ("mpi_set_cond: different sizes\n");
496 :
497 203224623 : for (i = 0; i < nlimbs; i++)
498 : {
499 188515048 : x = mask & (w->d[i] ^ u->d[i]);
500 188515048 : w->d[i] = w->d[i] ^ x;
501 : }
502 :
503 14709575 : x = mask & (w->nlimbs ^ u->nlimbs);
504 14709575 : w->nlimbs = w->nlimbs ^ x;
505 :
506 14709575 : x = mask & (w->sign ^ u->sign);
507 14709575 : w->sign = w->sign ^ x;
508 14709575 : return w;
509 : }
510 :
511 :
512 : gcry_mpi_t
513 21904 : _gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
514 : {
515 21904 : if (!w)
516 35 : w = _gcry_mpi_alloc (1);
517 : /* FIXME: If U is 0 we have no need to resize and thus possible
518 : allocating the the limbs. */
519 21904 : if (mpi_is_immutable (w))
520 : {
521 0 : mpi_immutable_failed ();
522 0 : return w;
523 : }
524 21904 : RESIZE_IF_NEEDED(w, 1);
525 21904 : w->d[0] = u;
526 21904 : w->nlimbs = u? 1:0;
527 21904 : w->sign = 0;
528 21904 : w->flags = 0;
529 21904 : return w;
530 : }
531 :
532 : gcry_err_code_t
533 0 : _gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
534 : {
535 0 : gcry_err_code_t err = GPG_ERR_NO_ERROR;
536 0 : unsigned long x = 0;
537 :
538 0 : if (w->nlimbs > 1)
539 0 : err = GPG_ERR_TOO_LARGE;
540 0 : else if (w->nlimbs == 1)
541 0 : x = w->d[0];
542 : else
543 0 : x = 0;
544 :
545 0 : if (! err)
546 0 : *u = x;
547 :
548 0 : return err;
549 : }
550 :
551 :
552 : gcry_mpi_t
553 16095 : _gcry_mpi_alloc_set_ui( unsigned long u)
554 : {
555 16095 : gcry_mpi_t w = mpi_alloc(1);
556 16095 : w->d[0] = u;
557 16095 : w->nlimbs = u? 1:0;
558 16095 : w->sign = 0;
559 16095 : return w;
560 : }
561 :
562 : void
563 10 : _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
564 : {
565 : struct gcry_mpi tmp;
566 :
567 10 : tmp = *a; *a = *b; *b = tmp;
568 10 : }
569 :
570 :
571 : void
572 0 : _gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap)
573 : {
574 : mpi_size_t i;
575 0 : mpi_size_t nlimbs = a->alloced;
576 0 : mpi_limb_t mask = ((mpi_limb_t)0) - !!swap;
577 : mpi_limb_t x;
578 :
579 0 : if (a->alloced != b->alloced)
580 0 : log_bug ("mpi_swap_cond: different sizes\n");
581 :
582 0 : for (i = 0; i < nlimbs; i++)
583 : {
584 0 : x = mask & (a->d[i] ^ b->d[i]);
585 0 : a->d[i] = a->d[i] ^ x;
586 0 : b->d[i] = b->d[i] ^ x;
587 : }
588 :
589 0 : x = mask & (a->nlimbs ^ b->nlimbs);
590 0 : a->nlimbs = a->nlimbs ^ x;
591 0 : b->nlimbs = b->nlimbs ^ x;
592 :
593 0 : x = mask & (a->sign ^ b->sign);
594 0 : a->sign = a->sign ^ x;
595 0 : b->sign = b->sign ^ x;
596 0 : }
597 :
598 :
599 : gcry_mpi_t
600 51257 : _gcry_mpi_new (unsigned int nbits)
601 : {
602 51257 : return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
603 : / BITS_PER_MPI_LIMB );
604 : }
605 :
606 :
607 : gcry_mpi_t
608 3428 : _gcry_mpi_snew (unsigned int nbits)
609 : {
610 3428 : return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
611 : / BITS_PER_MPI_LIMB );
612 : }
613 :
614 : void
615 91308 : _gcry_mpi_release( gcry_mpi_t a )
616 : {
617 91308 : _gcry_mpi_free( a );
618 91308 : }
619 :
620 : void
621 6806 : _gcry_mpi_randomize (gcry_mpi_t w,
622 : unsigned int nbits, enum gcry_random_level level)
623 : {
624 : unsigned char *p;
625 6806 : size_t nbytes = (nbits+7)/8;
626 :
627 6806 : if (mpi_is_immutable (w))
628 : {
629 0 : mpi_immutable_failed ();
630 6806 : return;
631 : }
632 6806 : if (level == GCRY_WEAK_RANDOM)
633 : {
634 6733 : p = mpi_is_secure(w) ? xmalloc_secure (nbytes)
635 : : xmalloc (nbytes);
636 6733 : _gcry_create_nonce (p, nbytes);
637 : }
638 : else
639 : {
640 73 : p = mpi_is_secure(w) ? _gcry_random_bytes_secure (nbytes, level)
641 : : _gcry_random_bytes (nbytes, level);
642 : }
643 6806 : _gcry_mpi_set_buffer( w, p, nbytes, 0 );
644 6806 : xfree (p);
645 : }
646 :
647 :
648 : void
649 2 : _gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
650 : {
651 2 : switch (flag)
652 : {
653 0 : case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
654 1 : case GCRYMPI_FLAG_CONST: a->flags |= (16|32); break;
655 1 : case GCRYMPI_FLAG_IMMUTABLE: a->flags |= 16; break;
656 :
657 : case GCRYMPI_FLAG_USER1:
658 : case GCRYMPI_FLAG_USER2:
659 : case GCRYMPI_FLAG_USER3:
660 0 : case GCRYMPI_FLAG_USER4: a->flags |= flag; break;
661 :
662 : case GCRYMPI_FLAG_OPAQUE:
663 0 : default: log_bug("invalid flag value\n");
664 : }
665 2 : }
666 :
667 : void
668 2 : _gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
669 : {
670 : (void)a; /* Not yet used. */
671 :
672 2 : switch (flag)
673 : {
674 : case GCRYMPI_FLAG_IMMUTABLE:
675 2 : if (!(a->flags & 32))
676 1 : a->flags &= ~16;
677 2 : break;
678 :
679 : case GCRYMPI_FLAG_USER1:
680 : case GCRYMPI_FLAG_USER2:
681 : case GCRYMPI_FLAG_USER3:
682 : case GCRYMPI_FLAG_USER4:
683 0 : a->flags &= ~flag;
684 0 : break;
685 :
686 : case GCRYMPI_FLAG_CONST:
687 : case GCRYMPI_FLAG_SECURE:
688 : case GCRYMPI_FLAG_OPAQUE:
689 0 : default: log_bug("invalid flag value\n");
690 : }
691 2 : }
692 :
693 : int
694 7344 : _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
695 : {
696 7344 : switch (flag)
697 : {
698 3587 : case GCRYMPI_FLAG_SECURE: return !!(a->flags & 1);
699 3737 : case GCRYMPI_FLAG_OPAQUE: return !!(a->flags & 4);
700 10 : case GCRYMPI_FLAG_IMMUTABLE: return !!(a->flags & 16);
701 10 : case GCRYMPI_FLAG_CONST: return !!(a->flags & 32);
702 : case GCRYMPI_FLAG_USER1:
703 : case GCRYMPI_FLAG_USER2:
704 : case GCRYMPI_FLAG_USER3:
705 0 : case GCRYMPI_FLAG_USER4: return !!(a->flags & flag);
706 0 : default: log_bug("invalid flag value\n");
707 : }
708 : /*NOTREACHED*/
709 : return 0;
710 : }
711 :
712 :
713 : /* Return a constant MPI descripbed by NO which is one of the
714 : MPI_C_xxx macros. There is no need to copy this returned value; it
715 : may be used directly. */
716 : gcry_mpi_t
717 654649 : _gcry_mpi_const (enum gcry_mpi_constants no)
718 : {
719 654649 : if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS)
720 0 : log_bug("invalid mpi_const selector %d\n", no);
721 654649 : if (!constants[no])
722 0 : log_bug("MPI subsystem not initialized\n");
723 654649 : return constants[no];
724 : }
|