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 
32 #if SIZEOF_UNSIGNED_INT == 2
33 # define MY_UINT_MAX 0xffff
34 /* (visual check:      0123 ) */
35 #elif SIZEOF_UNSIGNED_INT == 4
36 # define MY_UINT_MAX 0xffffffff
37 /* (visual check:      01234567 ) */
38 #elif SIZEOF_UNSIGNED_INT == 8
39 # define MY_UINT_MAX 0xffffffffffffffff
40 /* (visual check:      0123456789abcdef ) */
41 #else
42 # error Need MY_UINT_MAX for this limb size
43 #endif
44 
45 
46 /* Constants allocated right away at startup.  */
47 static gcry_mpi_t constants[MPI_NUMBER_OF_CONSTANTS];
48 
49 /* These variables are used to generate masks from conditional operation
50  * flag parameters.  Use of volatile prevents compiler optimizations from
51  * converting AND-masking to conditional branches.  */
52 static volatile mpi_limb_t vzero = 0;
53 static volatile mpi_limb_t vone = 1;
54 
55 
56 const char *
_gcry_mpi_get_hw_config(void)57 _gcry_mpi_get_hw_config (void)
58 {
59   return mod_source_info + 1;
60 }
61 
62 
63 /* Initialize the MPI subsystem.  This is called early and allows to
64    do some initialization without taking care of threading issues.  */
65 gcry_err_code_t
_gcry_mpi_init(void)66 _gcry_mpi_init (void)
67 {
68   int idx;
69   unsigned long value;
70 
71   for (idx=0; idx < MPI_NUMBER_OF_CONSTANTS; idx++)
72     {
73       switch (idx)
74         {
75         case MPI_C_ZERO:  value = 0; break;
76         case MPI_C_ONE:   value = 1; break;
77         case MPI_C_TWO:   value = 2; break;
78         case MPI_C_THREE: value = 3; break;
79         case MPI_C_FOUR:  value = 4; break;
80         case MPI_C_EIGHT: value = 8; break;
81         default: log_bug ("invalid mpi_const selector %d\n", idx);
82         }
83       constants[idx] = mpi_alloc_set_ui (value);
84       constants[idx]->flags = (16|32);
85     }
86 
87   return 0;
88 }
89 
90 
91 /****************
92  * Note:  It was a bad idea to use the number of limbs to allocate
93  *	  because on a alpha the limbs are large but we normally need
94  *	  integers of n bits - So we should change this to bits (or bytes).
95  *
96  *	  But mpi_alloc is used in a lot of places :-(.  New code
97  *	  should use mpi_new.
98  */
99 gcry_mpi_t
_gcry_mpi_alloc(unsigned nlimbs)100 _gcry_mpi_alloc( unsigned nlimbs )
101 {
102     gcry_mpi_t a;
103 
104     a = xmalloc( sizeof *a );
105     a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
106     a->alloced = nlimbs;
107     a->nlimbs = 0;
108     a->sign = 0;
109     a->flags = 0;
110     return a;
111 }
112 
113 void
_gcry_mpi_m_check(gcry_mpi_t a)114 _gcry_mpi_m_check( gcry_mpi_t a )
115 {
116     _gcry_check_heap(a);
117     _gcry_check_heap(a->d);
118 }
119 
120 gcry_mpi_t
_gcry_mpi_alloc_secure(unsigned nlimbs)121 _gcry_mpi_alloc_secure( unsigned nlimbs )
122 {
123     gcry_mpi_t a;
124 
125     a = xmalloc( sizeof *a );
126     a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
127     a->alloced = nlimbs;
128     a->flags = 1;
129     a->nlimbs = 0;
130     a->sign = 0;
131     return a;
132 }
133 
134 
135 
136 mpi_ptr_t
_gcry_mpi_alloc_limb_space(unsigned int nlimbs,int secure)137 _gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
138 {
139     mpi_ptr_t p;
140     size_t len;
141 
142     len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
143     p = secure ? xmalloc_secure (len) : xmalloc (len);
144     if (! nlimbs)
145       *p = 0;
146 
147     return p;
148 }
149 
150 void
_gcry_mpi_free_limb_space(mpi_ptr_t a,unsigned int nlimbs)151 _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
152 {
153   if (a)
154     {
155       size_t len = nlimbs * sizeof(mpi_limb_t);
156 
157       /* If we have information on the number of allocated limbs, we
158          better wipe that space out.  This is a failsafe feature if
159          secure memory has been disabled or was not properly
160          implemented in user provided allocation functions. */
161       if (len)
162         wipememory (a, len);
163       xfree(a);
164     }
165 }
166 
167 
168 void
_gcry_mpi_assign_limb_space(gcry_mpi_t a,mpi_ptr_t ap,unsigned int nlimbs)169 _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
170 {
171   _gcry_mpi_free_limb_space (a->d, a->alloced);
172   a->d = ap;
173   a->alloced = nlimbs;
174 }
175 
176 
177 
178 /****************
179  * Resize the array of A to NLIMBS. The additional space is cleared
180  * (set to 0).
181  */
182 void
_gcry_mpi_resize(gcry_mpi_t a,unsigned nlimbs)183 _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
184 {
185   size_t i;
186 
187   if (nlimbs <= a->alloced)
188     {
189       /* We only need to clear the new space (this is a nop if the
190          limb space is already of the correct size. */
191       for (i=a->nlimbs; i < a->alloced; i++)
192         a->d[i] = 0;
193       return;
194     }
195 
196   /* Actually resize the limb space.  */
197   if (a->d)
198     {
199       a->d = xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
200       for (i=a->alloced; i < nlimbs; i++)
201         a->d[i] = 0;
202     }
203   else
204     {
205       if (a->flags & 1)
206 	/* Secure memory is wanted.  */
207 	a->d = xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
208       else
209 	/* Standard memory.  */
210 	a->d = xcalloc (nlimbs , sizeof (mpi_limb_t));
211     }
212   a->alloced = nlimbs;
213 }
214 
215 void
_gcry_mpi_clear(gcry_mpi_t a)216 _gcry_mpi_clear( gcry_mpi_t a )
217 {
218   if (mpi_is_immutable (a))
219     {
220       mpi_immutable_failed ();
221       return;
222     }
223   a->nlimbs = 0;
224   a->flags = 0;
225 }
226 
227 
228 void
_gcry_mpi_free(gcry_mpi_t a)229 _gcry_mpi_free( gcry_mpi_t a )
230 {
231   if (!a )
232     return;
233   if ((a->flags & 32))
234   {
235 #if GPGRT_VERSION_NUMBER >= 0x011600  /* 1.22 */
236     gpgrt_annotate_leaked_object(a);
237 #endif
238     return; /* Never release a constant. */
239   }
240   if ((a->flags & 4))
241     xfree( a->d );
242   else
243     {
244       _gcry_mpi_free_limb_space(a->d, a->alloced);
245     }
246   /* Check that the flags makes sense.  We better allow for bit 1
247      (value 2) for backward ABI compatibility.  */
248   if ((a->flags & ~(1|2|4|16
249                     |GCRYMPI_FLAG_USER1
250                     |GCRYMPI_FLAG_USER2
251                     |GCRYMPI_FLAG_USER3
252                     |GCRYMPI_FLAG_USER4)))
253     log_bug("invalid flag value in mpi_free\n");
254   xfree (a);
255 }
256 
257 
258 void
_gcry_mpi_immutable_failed(void)259 _gcry_mpi_immutable_failed (void)
260 {
261   log_info ("Warning: trying to change an immutable MPI\n");
262 }
263 
264 
265 static void
mpi_set_secure(gcry_mpi_t a)266 mpi_set_secure( gcry_mpi_t a )
267 {
268   mpi_ptr_t ap, bp;
269 
270   if ( (a->flags & 1) )
271     return;
272   a->flags |= 1;
273   ap = a->d;
274   if (!a->nlimbs)
275     {
276       gcry_assert (!ap);
277       return;
278     }
279   bp = mpi_alloc_limb_space (a->alloced, 1);
280   MPN_COPY( bp, ap, a->nlimbs );
281   a->d = bp;
282   _gcry_mpi_free_limb_space (ap, a->alloced);
283 }
284 
285 
286 gcry_mpi_t
_gcry_mpi_set_opaque(gcry_mpi_t a,void * p,unsigned int nbits)287 _gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
288 {
289   if (!a)
290     a = mpi_alloc(0);
291 
292   if (mpi_is_immutable (a))
293     {
294       mpi_immutable_failed ();
295       return a;
296     }
297 
298   if( a->flags & 4 )
299     xfree (a->d);
300   else
301     _gcry_mpi_free_limb_space (a->d, a->alloced);
302 
303   a->d = p;
304   a->alloced = 0;
305   a->nlimbs = 0;
306   a->sign  = nbits;
307   a->flags = 4 | (a->flags & (GCRYMPI_FLAG_USER1|GCRYMPI_FLAG_USER2
308                               |GCRYMPI_FLAG_USER3|GCRYMPI_FLAG_USER4));
309   if (_gcry_is_secure (a->d))
310     a->flags |= 1;
311   return a;
312 }
313 
314 
315 gcry_mpi_t
_gcry_mpi_set_opaque_copy(gcry_mpi_t a,const void * p,unsigned int nbits)316 _gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits)
317 {
318   void *d;
319   unsigned int n;
320 
321   n = (nbits+7)/8;
322   d = _gcry_is_secure (p)? xtrymalloc_secure (n) : xtrymalloc (n);
323   if (!d)
324     return NULL;
325   memcpy (d, p, n);
326   return mpi_set_opaque (a, d, nbits);
327 }
328 
329 
330 void *
_gcry_mpi_get_opaque(gcry_mpi_t a,unsigned int * nbits)331 _gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
332 {
333     if( !(a->flags & 4) )
334 	log_bug("mpi_get_opaque on normal mpi\n");
335     if( nbits )
336 	*nbits = a->sign;
337     return a->d;
338 }
339 
340 
341 void *
_gcry_mpi_get_opaque_copy(gcry_mpi_t a,unsigned int * nbits)342 _gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits)
343 {
344   const void *s;
345   void *d;
346   unsigned int n;
347 
348   s = mpi_get_opaque (a, nbits);
349   if (!s && nbits)
350     return NULL;
351   n = (*nbits+7)/8;
352   d = _gcry_is_secure (s)? xtrymalloc_secure (n) : xtrymalloc (n);
353   if (d)
354     memcpy (d, s, n);
355   return d;
356 }
357 
358 /****************
359  * Note: This copy function should not interpret the MPI
360  *	 but copy it transparently.
361  */
362 gcry_mpi_t
_gcry_mpi_copy(gcry_mpi_t a)363 _gcry_mpi_copy (gcry_mpi_t a)
364 {
365     int i;
366     gcry_mpi_t b;
367 
368     if( a && (a->flags & 4) ) {
369         void *p = _gcry_is_secure(a->d)? xmalloc_secure ((a->sign+7)/8)
370                                        : xmalloc ((a->sign+7)/8);
371         if (a->d)
372           memcpy( p, a->d, (a->sign+7)/8 );
373         b = mpi_set_opaque( NULL, p, a->sign );
374         b->flags = a->flags;
375         b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
376     }
377     else if( a ) {
378 	b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
379 			    : mpi_alloc( a->nlimbs );
380 	b->nlimbs = a->nlimbs;
381 	b->sign = a->sign;
382 	b->flags  = a->flags;
383         b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
384 	for(i=0; i < b->nlimbs; i++ )
385 	    b->d[i] = a->d[i];
386     }
387     else
388 	b = NULL;
389     return b;
390 }
391 
392 
393 /* Return true if A is negative.  */
394 int
_gcry_mpi_is_neg(gcry_mpi_t a)395 _gcry_mpi_is_neg (gcry_mpi_t a)
396 {
397   if (a->sign && _gcry_mpi_cmp_ui (a, 0))
398     return 1;
399   else
400     return 0;
401 }
402 
403 
404 /* W = - U */
405 void
_gcry_mpi_neg(gcry_mpi_t w,gcry_mpi_t u)406 _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u)
407 {
408   if (w != u)
409     mpi_set (w, u);
410   else if (mpi_is_immutable (w))
411     {
412       mpi_immutable_failed ();
413       return;
414     }
415 
416   w->sign = !u->sign;
417 }
418 
419 
420 /* W = [W] */
421 void
_gcry_mpi_abs(gcry_mpi_t w)422 _gcry_mpi_abs (gcry_mpi_t w)
423 {
424   if (mpi_is_immutable (w))
425     {
426       mpi_immutable_failed ();
427       return;
428     }
429 
430   w->sign = 0;
431 }
432 
433 
434 /****************
435  * This function allocates an MPI which is optimized to hold
436  * a value as large as the one given in the argument and allocates it
437  * with the same flags as A.
438  */
439 gcry_mpi_t
_gcry_mpi_alloc_like(gcry_mpi_t a)440 _gcry_mpi_alloc_like( gcry_mpi_t a )
441 {
442     gcry_mpi_t b;
443 
444     if( a && (a->flags & 4) ) {
445 	int n = (a->sign+7)/8;
446 	void *p = _gcry_is_secure(a->d)? xtrymalloc_secure (n)
447                                        : xtrymalloc (n);
448 	memcpy( p, a->d, n );
449 	b = mpi_set_opaque( NULL, p, a->sign );
450     }
451     else if( a ) {
452 	b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
453 			    : mpi_alloc( a->nlimbs );
454 	b->nlimbs = 0;
455 	b->sign = 0;
456 	b->flags = a->flags;
457     }
458     else
459 	b = NULL;
460     return b;
461 }
462 
463 
464 /* Set U into W and release U.  If W is NULL only U will be released. */
465 void
_gcry_mpi_snatch(gcry_mpi_t w,gcry_mpi_t u)466 _gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u)
467 {
468   if (w)
469     {
470       if (mpi_is_immutable (w))
471         {
472           mpi_immutable_failed ();
473           return;
474         }
475       _gcry_mpi_assign_limb_space (w, u->d, u->alloced);
476       w->nlimbs = u->nlimbs;
477       w->sign   = u->sign;
478       w->flags  = u->flags;
479       u->alloced = 0;
480       u->nlimbs = 0;
481       u->d = NULL;
482     }
483   _gcry_mpi_free (u);
484 }
485 
486 
487 gcry_mpi_t
_gcry_mpi_set(gcry_mpi_t w,gcry_mpi_t u)488 _gcry_mpi_set (gcry_mpi_t w, gcry_mpi_t u)
489 {
490   mpi_ptr_t wp, up;
491   mpi_size_t usize = u->nlimbs;
492   int usign = u->sign;
493 
494   if (!w)
495     w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
496   if (mpi_is_immutable (w))
497     {
498       mpi_immutable_failed ();
499       return w;
500     }
501   RESIZE_IF_NEEDED(w, usize);
502   wp = w->d;
503   up = u->d;
504   MPN_COPY( wp, up, usize );
505   w->nlimbs = usize;
506   w->flags = u->flags;
507   w->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
508   w->sign = usign;
509   return w;
510 }
511 
512 /****************
513  * Set the value of W by the one of U, when SET is 1.
514  * Leave the value when SET is 0.
515  * This implementation should be constant-time regardless of SET.
516  */
517 gcry_mpi_t
_gcry_mpi_set_cond(gcry_mpi_t w,const gcry_mpi_t u,unsigned long set)518 _gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u, unsigned long set)
519 {
520   mpi_size_t i;
521   mpi_size_t nlimbs = u->alloced;
522   mpi_limb_t mask1 = vzero - set;
523   mpi_limb_t mask2 = set - vone;
524   mpi_limb_t xu;
525   mpi_limb_t xw;
526   mpi_limb_t *uu = u->d;
527   mpi_limb_t *uw = w->d;
528 
529   if (w->alloced != u->alloced)
530     log_bug ("mpi_set_cond: different sizes\n");
531 
532   for (i = 0; i < nlimbs; i++)
533     {
534       xu = uu[i];
535       xw = uw[i];
536       uw[i] = (xw & mask2) | (xu & mask1);
537     }
538 
539   xu = u->nlimbs;
540   xw = w->nlimbs;
541   w->nlimbs = (xw & mask2) | (xu & mask1);
542 
543   xu = u->sign;
544   xw = w->sign;
545   w->sign = (xw & mask2) | (xu & mask1);
546   return w;
547 }
548 
549 
550 gcry_mpi_t
_gcry_mpi_set_ui(gcry_mpi_t w,unsigned long u)551 _gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
552 {
553   if (!w)
554     w = _gcry_mpi_alloc (1);
555   /* FIXME: If U is 0 we have no need to resize and thus possible
556      allocating the the limbs. */
557   if (mpi_is_immutable (w))
558     {
559       mpi_immutable_failed ();
560       return w;
561     }
562   RESIZE_IF_NEEDED(w, 1);
563   w->d[0] = u;
564   w->nlimbs = u? 1:0;
565   w->sign = 0;
566   w->flags = 0;
567   return w;
568 }
569 
570 /* If U is non-negative and small enough store it as an unsigned int
571  * at W.  If the value does not fit into an unsigned int or is
572  * negative return GPG_ERR_ERANGE.  Note that we return an unsigned
573  * int so that the value can be used with the bit test functions; in
574  * contrast the other _ui functions take an unsigned long so that on
575  * some platforms they may accept a larger value.  On error the value
576  * at W is not changed. */
577 gcry_err_code_t
_gcry_mpi_get_ui(unsigned int * w,gcry_mpi_t u)578 _gcry_mpi_get_ui (unsigned int *w, gcry_mpi_t u)
579 {
580   mpi_limb_t x;
581 
582   if (u->nlimbs > 1 || u->sign)
583     return GPG_ERR_ERANGE;
584 
585   x = (u->nlimbs == 1) ? u->d[0] : 0;
586   if (sizeof (x) > sizeof (unsigned int) && x > MY_UINT_MAX)
587     return GPG_ERR_ERANGE;
588 
589   *w = x;
590   return 0;
591 }
592 
593 
594 gcry_mpi_t
_gcry_mpi_alloc_set_ui(unsigned long u)595 _gcry_mpi_alloc_set_ui( unsigned long u)
596 {
597     gcry_mpi_t w = mpi_alloc(1);
598     w->d[0] = u;
599     w->nlimbs = u? 1:0;
600     w->sign = 0;
601     return w;
602 }
603 
604 void
_gcry_mpi_swap(gcry_mpi_t a,gcry_mpi_t b)605 _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
606 {
607     struct gcry_mpi tmp;
608 
609     tmp = *a; *a = *b; *b = tmp;
610 }
611 
612 
613 /****************
614  * Swap the value of A and B, when SWAP is 1.
615  * Leave the value when SWAP is 0.
616  * This implementation should be constant-time regardless of SWAP.
617  */
618 void
_gcry_mpi_swap_cond(gcry_mpi_t a,gcry_mpi_t b,unsigned long swap)619 _gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap)
620 {
621   mpi_size_t i;
622   mpi_size_t nlimbs;
623   mpi_limb_t mask1 = vzero - swap;
624   mpi_limb_t mask2 = swap - vone;
625   mpi_limb_t *ua = a->d;
626   mpi_limb_t *ub = b->d;
627   mpi_limb_t xa;
628   mpi_limb_t xb;
629 
630   if (a->alloced > b->alloced)
631     nlimbs = b->alloced;
632   else
633     nlimbs = a->alloced;
634   if (a->nlimbs > nlimbs || b->nlimbs > nlimbs)
635     log_bug ("mpi_swap_cond: different sizes\n");
636 
637   for (i = 0; i < nlimbs; i++)
638     {
639       xa = ua[i];
640       xb = ub[i];
641       ua[i] = (xa & mask2) | (xb & mask1);
642       ub[i] = (xa & mask1) | (xb & mask2);
643     }
644 
645   xa = a->nlimbs;
646   xb = b->nlimbs;
647   a->nlimbs = (xa & mask2) | (xb & mask1);
648   b->nlimbs = (xa & mask1) | (xb & mask2);
649 
650   xa = a->sign;
651   xb = b->sign;
652   a->sign = (xa & mask2) | (xb & mask1);
653   b->sign = (xa & mask1) | (xb & mask2);
654 }
655 
656 
657 /****************
658  * Set bit N of A, when SET is 1.
659  * This implementation should be constant-time regardless of SET.
660  */
661 void
_gcry_mpi_set_bit_cond(gcry_mpi_t a,unsigned int n,unsigned long set)662 _gcry_mpi_set_bit_cond (gcry_mpi_t a, unsigned int n, unsigned long set)
663 {
664   unsigned int limbno, bitno;
665   mpi_limb_t set_the_bit = !!set;
666 
667   limbno = n / BITS_PER_MPI_LIMB;
668   bitno  = n % BITS_PER_MPI_LIMB;
669 
670   a->d[limbno] |= (set_the_bit<<bitno);
671 }
672 
673 
674 gcry_mpi_t
_gcry_mpi_new(unsigned int nbits)675 _gcry_mpi_new (unsigned int nbits)
676 {
677     return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
678                              / BITS_PER_MPI_LIMB );
679 }
680 
681 
682 gcry_mpi_t
_gcry_mpi_snew(unsigned int nbits)683 _gcry_mpi_snew (unsigned int nbits)
684 {
685   return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
686                                   / BITS_PER_MPI_LIMB );
687 }
688 
689 void
_gcry_mpi_release(gcry_mpi_t a)690 _gcry_mpi_release( gcry_mpi_t a )
691 {
692     _gcry_mpi_free( a );
693 }
694 
695 void
_gcry_mpi_randomize(gcry_mpi_t w,unsigned int nbits,enum gcry_random_level level)696 _gcry_mpi_randomize (gcry_mpi_t w,
697                      unsigned int nbits, enum gcry_random_level level)
698 {
699   unsigned char *p;
700   size_t nbytes = (nbits+7)/8;
701 
702   if (mpi_is_immutable (w))
703     {
704       mpi_immutable_failed ();
705       return;
706     }
707   if (level == GCRY_WEAK_RANDOM)
708     {
709       p = mpi_is_secure(w) ? xmalloc_secure (nbytes)
710                            : xmalloc (nbytes);
711       _gcry_create_nonce (p, nbytes);
712     }
713   else
714     {
715       p = mpi_is_secure(w) ? _gcry_random_bytes_secure (nbytes, level)
716                            : _gcry_random_bytes (nbytes, level);
717     }
718   _gcry_mpi_set_buffer( w, p, nbytes, 0 );
719   xfree (p);
720 }
721 
722 
723 void
_gcry_mpi_set_flag(gcry_mpi_t a,enum gcry_mpi_flag flag)724 _gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
725 {
726   switch (flag)
727     {
728     case GCRYMPI_FLAG_SECURE:     mpi_set_secure(a); break;
729     case GCRYMPI_FLAG_CONST:      a->flags |= (16|32); break;
730     case GCRYMPI_FLAG_IMMUTABLE:  a->flags |= 16; break;
731 
732     case GCRYMPI_FLAG_USER1:
733     case GCRYMPI_FLAG_USER2:
734     case GCRYMPI_FLAG_USER3:
735     case GCRYMPI_FLAG_USER4:      a->flags |= flag; break;
736 
737     case GCRYMPI_FLAG_OPAQUE:
738     default: log_bug("invalid flag value\n");
739     }
740 }
741 
742 void
_gcry_mpi_clear_flag(gcry_mpi_t a,enum gcry_mpi_flag flag)743 _gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
744 {
745   (void)a; /* Not yet used. */
746 
747   switch (flag)
748     {
749     case GCRYMPI_FLAG_IMMUTABLE:
750       if (!(a->flags & 32))
751         a->flags &= ~16;
752       break;
753 
754     case GCRYMPI_FLAG_USER1:
755     case GCRYMPI_FLAG_USER2:
756     case GCRYMPI_FLAG_USER3:
757     case GCRYMPI_FLAG_USER4:
758       a->flags &= ~flag;
759       break;
760 
761     case GCRYMPI_FLAG_CONST:
762     case GCRYMPI_FLAG_SECURE:
763     case GCRYMPI_FLAG_OPAQUE:
764     default: log_bug("invalid flag value\n");
765     }
766 }
767 
768 int
_gcry_mpi_get_flag(gcry_mpi_t a,enum gcry_mpi_flag flag)769 _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
770 {
771   switch (flag)
772     {
773     case GCRYMPI_FLAG_SECURE:    return !!(a->flags & 1);
774     case GCRYMPI_FLAG_OPAQUE:    return !!(a->flags & 4);
775     case GCRYMPI_FLAG_IMMUTABLE: return !!(a->flags & 16);
776     case GCRYMPI_FLAG_CONST:     return !!(a->flags & 32);
777     case GCRYMPI_FLAG_USER1:
778     case GCRYMPI_FLAG_USER2:
779     case GCRYMPI_FLAG_USER3:
780     case GCRYMPI_FLAG_USER4:     return !!(a->flags & flag);
781     default: log_bug("invalid flag value\n");
782     }
783   /*NOTREACHED*/
784   return 0;
785 }
786 
787 
788 /* Return a constant MPI descripbed by NO which is one of the
789    MPI_C_xxx macros.  There is no need to copy this returned value; it
790    may be used directly.  */
791 gcry_mpi_t
_gcry_mpi_const(enum gcry_mpi_constants no)792 _gcry_mpi_const (enum gcry_mpi_constants no)
793 {
794   if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS)
795     log_bug("invalid mpi_const selector %d\n", no);
796   if (!constants[no])
797     log_bug("MPI subsystem not initialized\n");
798   return constants[no];
799 }
800