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