57fe72a7951a59e24e7f505bf84c9627da07bbe2
[libgcrypt.git] / mpi / mpiutil.c
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 /* Constatns allocated right away at strtartup.  */
32 static gcry_mpi_t constants[MPI_NUMBER_OF_CONSTANTS];
33
34
35
36 const char *
37 _gcry_mpi_get_hw_config (void)
38 {
39   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 _gcry_mpi_init (void)
47 {
48   int idx;
49   unsigned long value;
50
51   for (idx=0; idx < MPI_NUMBER_OF_CONSTANTS; idx++)
52     {
53       switch (idx)
54         {
55         case MPI_C_ZERO:  value = 0; break;
56         case MPI_C_ONE:   value = 1; break;
57         case MPI_C_TWO:   value = 2; break;
58         case MPI_C_THREE: value = 3; break;
59         case MPI_C_FOUR:  value = 4; break;
60         case MPI_C_EIGHT: value = 8; break;
61         default: log_bug ("invalid mpi_const selector %d\n", idx);
62         }
63       constants[idx] = mpi_alloc_set_ui (value);
64       constants[idx]->flags = (16|32);
65     }
66
67   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 _gcry_mpi_alloc( unsigned nlimbs )
81 {
82     gcry_mpi_t a;
83
84     a = gcry_xmalloc( sizeof *a );
85     a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
86     a->alloced = nlimbs;
87     a->nlimbs = 0;
88     a->sign = 0;
89     a->flags = 0;
90     return a;
91 }
92
93 void
94 _gcry_mpi_m_check( gcry_mpi_t a )
95 {
96     _gcry_check_heap(a);
97     _gcry_check_heap(a->d);
98 }
99
100 gcry_mpi_t
101 _gcry_mpi_alloc_secure( unsigned nlimbs )
102 {
103     gcry_mpi_t a;
104
105     a = gcry_xmalloc( sizeof *a );
106     a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
107     a->alloced = nlimbs;
108     a->flags = 1;
109     a->nlimbs = 0;
110     a->sign = 0;
111     return a;
112 }
113
114
115
116 mpi_ptr_t
117 _gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
118 {
119     mpi_ptr_t p;
120     size_t len;
121
122     len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
123     p = secure ? gcry_xmalloc_secure (len) : gcry_xmalloc (len);
124     if (! nlimbs)
125       *p = 0;
126
127     return p;
128 }
129
130 void
131 _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
132 {
133   if (a)
134     {
135       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       if (len)
142         wipememory (a, len);
143       gcry_free(a);
144     }
145 }
146
147
148 void
149 _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
150 {
151   _gcry_mpi_free_limb_space (a->d, a->alloced);
152   a->d = ap;
153   a->alloced = nlimbs;
154 }
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 _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
164 {
165   size_t i;
166
167   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       for (i=a->nlimbs; i < a->alloced; i++)
172         a->d[i] = 0;
173       return;
174     }
175
176   /* Actually resize the limb space.  */
177   if (a->d)
178     {
179       a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
180       for (i=a->alloced; i < nlimbs; i++)
181         a->d[i] = 0;
182     }
183   else
184     {
185       if (a->flags & 1)
186         /* Secure memory is wanted.  */
187         a->d = gcry_xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
188       else
189         /* Standard memory.  */
190         a->d = gcry_xcalloc (nlimbs , sizeof (mpi_limb_t));
191     }
192   a->alloced = nlimbs;
193 }
194
195 void
196 _gcry_mpi_clear( gcry_mpi_t a )
197 {
198   if (mpi_is_immutable (a))
199     {
200       mpi_immutable_failed ();
201       return;
202     }
203   a->nlimbs = 0;
204   a->flags = 0;
205 }
206
207
208 void
209 _gcry_mpi_free( gcry_mpi_t a )
210 {
211   if (!a )
212     return;
213   if ((a->flags & 32))
214     return; /* Never release a constant. */
215   if ((a->flags & 4))
216     gcry_free( a->d );
217   else
218     {
219       _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   if ((a->flags & ~(1|2|4|16)))
224     log_bug("invalid flag value in mpi_free\n");
225   gcry_free(a);
226 }
227
228
229 void
230 _gcry_mpi_immutable_failed (void)
231 {
232   log_info ("Warning: trying to change an immutable MPI\n");
233 }
234
235
236 static void
237 mpi_set_secure( gcry_mpi_t a )
238 {
239   mpi_ptr_t ap, bp;
240
241   if ( (a->flags & 1) )
242     return;
243   a->flags |= 1;
244   ap = a->d;
245   if (!a->nlimbs)
246     {
247       gcry_assert (!ap);
248       return;
249     }
250   bp = mpi_alloc_limb_space (a->nlimbs, 1);
251   MPN_COPY( bp, ap, a->nlimbs );
252   a->d = bp;
253   _gcry_mpi_free_limb_space (ap, a->alloced);
254 }
255
256
257 gcry_mpi_t
258 gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits )
259 {
260   if (!a)
261     a = mpi_alloc(0);
262
263   if (mpi_is_immutable (a))
264     {
265       mpi_immutable_failed ();
266       return a;
267     }
268
269   if( a->flags & 4 )
270     gcry_free( a->d );
271   else
272     _gcry_mpi_free_limb_space (a->d, a->alloced);
273
274   a->d = p;
275   a->alloced = 0;
276   a->nlimbs = 0;
277   a->sign  = nbits;
278   a->flags = 4;
279   return a;
280 }
281
282
283 void *
284 gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits )
285 {
286     if( !(a->flags & 4) )
287         log_bug("mpi_get_opaque on normal mpi\n");
288     if( nbits )
289         *nbits = a->sign;
290     return a->d;
291 }
292
293
294 void *
295 _gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits)
296 {
297   const void *s;
298   void *d;
299   unsigned int n;
300
301   s = gcry_mpi_get_opaque (a, nbits);
302   if (!s && nbits)
303     return NULL;
304   n = (*nbits+7)/8;
305   d = gcry_is_secure (s)? gcry_malloc_secure (n) : gcry_malloc (n);
306   memcpy (d, s, n);
307   return d;
308 }
309
310 /****************
311  * Note: This copy function should not interpret the MPI
312  *       but copy it transparently.
313  */
314 gcry_mpi_t
315 gcry_mpi_copy( gcry_mpi_t a )
316 {
317     int i;
318     gcry_mpi_t b;
319
320     if( a && (a->flags & 4) ) {
321         void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 )
322                                      : gcry_xmalloc( (a->sign+7)/8 );
323         memcpy( p, a->d, (a->sign+7)/8 );
324         b = gcry_mpi_set_opaque( NULL, p, a->sign );
325         b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
326     }
327     else if( a ) {
328         b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
329                             : mpi_alloc( a->nlimbs );
330         b->nlimbs = a->nlimbs;
331         b->sign = a->sign;
332         b->flags  = a->flags;
333         b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
334         for(i=0; i < b->nlimbs; i++ )
335             b->d[i] = a->d[i];
336     }
337     else
338         b = NULL;
339     return b;
340 }
341
342
343 /* Return true if A is negative.  */
344 int
345 _gcry_mpi_is_neg (gcry_mpi_t a)
346 {
347   if (a->sign && _gcry_mpi_cmp_ui (a, 0))
348     return 1;
349   else
350     return 0;
351 }
352
353
354 /* W = - U */
355 void
356 _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u)
357 {
358   if (mpi_is_immutable (w))
359     {
360       mpi_immutable_failed ();
361       return;
362     }
363
364   w->sign = !u->sign;
365 }
366
367
368 /* W = [W] */
369 void
370 _gcry_mpi_abs (gcry_mpi_t w)
371 {
372   if (mpi_is_immutable (w))
373     {
374       mpi_immutable_failed ();
375       return;
376     }
377
378   w->sign = 0;
379 }
380
381
382 /****************
383  * This function allocates an MPI which is optimized to hold
384  * a value as large as the one given in the argument and allocates it
385  * with the same flags as A.
386  */
387 gcry_mpi_t
388 _gcry_mpi_alloc_like( gcry_mpi_t a )
389 {
390     gcry_mpi_t b;
391
392     if( a && (a->flags & 4) ) {
393         int n = (a->sign+7)/8;
394         void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n )
395                                      : gcry_malloc( n );
396         memcpy( p, a->d, n );
397         b = gcry_mpi_set_opaque( NULL, p, a->sign );
398     }
399     else if( a ) {
400         b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
401                             : mpi_alloc( a->nlimbs );
402         b->nlimbs = 0;
403         b->sign = 0;
404         b->flags = a->flags;
405     }
406     else
407         b = NULL;
408     return b;
409 }
410
411
412 /* Set U into W and release U.  If W is NULL only U will be released. */
413 void
414 gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u)
415 {
416   if (w)
417     {
418       if (mpi_is_immutable (w))
419         {
420           mpi_immutable_failed ();
421           return;
422         }
423       _gcry_mpi_assign_limb_space (w, u->d, u->alloced);
424       w->nlimbs = u->nlimbs;
425       w->sign   = u->sign;
426       w->flags  = u->flags;
427       u->alloced = 0;
428       u->nlimbs = 0;
429       u->d = NULL;
430     }
431   _gcry_mpi_free (u);
432 }
433
434
435 gcry_mpi_t
436 gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u)
437 {
438   mpi_ptr_t wp, up;
439   mpi_size_t usize = u->nlimbs;
440   int usign = u->sign;
441
442   if (!w)
443     w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
444   if (mpi_is_immutable (w))
445     {
446       mpi_immutable_failed ();
447       return w;
448     }
449   RESIZE_IF_NEEDED(w, usize);
450   wp = w->d;
451   up = u->d;
452   MPN_COPY( wp, up, usize );
453   w->nlimbs = usize;
454   w->flags = u->flags;
455   w->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
456   w->sign = usign;
457   return w;
458 }
459
460
461 gcry_mpi_t
462 gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u)
463 {
464   if (!w)
465     w = _gcry_mpi_alloc (1);
466   /* FIXME: If U is 0 we have no need to resize and thus possible
467      allocating the the limbs. */
468   if (mpi_is_immutable (w))
469     {
470       mpi_immutable_failed ();
471       return w;
472     }
473   RESIZE_IF_NEEDED(w, 1);
474   w->d[0] = u;
475   w->nlimbs = u? 1:0;
476   w->sign = 0;
477   w->flags = 0;
478   return w;
479 }
480
481 gcry_err_code_t
482 _gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
483 {
484   gcry_err_code_t err = GPG_ERR_NO_ERROR;
485   unsigned long x = 0;
486
487   if (w->nlimbs > 1)
488     err = GPG_ERR_TOO_LARGE;
489   else if (w->nlimbs == 1)
490     x = w->d[0];
491   else
492     x = 0;
493
494   if (! err)
495     *u = x;
496
497   return err;
498 }
499
500 gcry_error_t
501 gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
502 {
503   gcry_err_code_t err = GPG_ERR_NO_ERROR;
504
505   err = _gcry_mpi_get_ui (w, u);
506
507   return gcry_error (err);
508 }
509
510 gcry_mpi_t
511 _gcry_mpi_alloc_set_ui( unsigned long u)
512 {
513     gcry_mpi_t w = mpi_alloc(1);
514     w->d[0] = u;
515     w->nlimbs = u? 1:0;
516     w->sign = 0;
517     return w;
518 }
519
520 void
521 gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
522 {
523     struct gcry_mpi tmp;
524
525     tmp = *a; *a = *b; *b = tmp;
526 }
527
528
529 gcry_mpi_t
530 gcry_mpi_new( unsigned int nbits )
531 {
532     return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
533                              / BITS_PER_MPI_LIMB );
534 }
535
536
537 gcry_mpi_t
538 gcry_mpi_snew( unsigned int nbits )
539 {
540   return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
541                                   / BITS_PER_MPI_LIMB );
542 }
543
544 void
545 gcry_mpi_release( gcry_mpi_t a )
546 {
547     _gcry_mpi_free( a );
548 }
549
550 void
551 gcry_mpi_randomize( gcry_mpi_t w,
552                     unsigned int nbits, enum gcry_random_level level )
553 {
554   unsigned char *p;
555   size_t nbytes = (nbits+7)/8;
556
557   if (mpi_is_immutable (w))
558     {
559       mpi_immutable_failed ();
560       return;
561     }
562   if (level == GCRY_WEAK_RANDOM)
563     {
564       p = mpi_is_secure(w) ? gcry_xmalloc_secure (nbytes)
565                            : gcry_xmalloc (nbytes);
566       gcry_create_nonce (p, nbytes);
567     }
568   else
569     {
570       p = mpi_is_secure(w) ? gcry_random_bytes_secure (nbytes, level)
571                            : gcry_random_bytes (nbytes, level);
572     }
573   _gcry_mpi_set_buffer( w, p, nbytes, 0 );
574   gcry_free (p);
575 }
576
577
578 void
579 gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
580 {
581   switch (flag)
582     {
583     case GCRYMPI_FLAG_SECURE:     mpi_set_secure(a); break;
584     case GCRYMPI_FLAG_CONST:      a->flags |= (16|32); break;
585     case GCRYMPI_FLAG_IMMUTABLE:  a->flags |= 16; break;
586     case GCRYMPI_FLAG_OPAQUE:
587     default: log_bug("invalid flag value\n");
588     }
589 }
590
591 void
592 gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
593 {
594   (void)a; /* Not yet used. */
595
596   switch (flag)
597     {
598     case GCRYMPI_FLAG_IMMUTABLE:
599       if (!(a->flags & 32))
600         a->flags &= ~16;
601       break;
602     case GCRYMPI_FLAG_CONST:
603     case GCRYMPI_FLAG_SECURE:
604     case GCRYMPI_FLAG_OPAQUE:
605     default: log_bug("invalid flag value\n");
606     }
607 }
608
609 int
610 gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
611 {
612   switch (flag)
613     {
614     case GCRYMPI_FLAG_SECURE:    return !!(a->flags & 1);
615     case GCRYMPI_FLAG_OPAQUE:    return !!(a->flags & 4);
616     case GCRYMPI_FLAG_IMMUTABLE: return !!(a->flags & 16);
617     case GCRYMPI_FLAG_CONST:     return !!(a->flags & 32);
618     default: log_bug("invalid flag value\n");
619     }
620   /*NOTREACHED*/
621   return 0;
622 }
623
624
625 /* Return a constant MPI descripbed by NO which is one of the
626    MPI_C_xxx macros.  There is no need to copy this returned value; it
627    may be used directly.  */
628 gcry_mpi_t
629 _gcry_mpi_const (enum gcry_mpi_constants no)
630 {
631   if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS)
632     log_bug("invalid mpi_const selector %d\n", no);
633   if (!constants[no])
634     log_bug("MPI subsystem not initialized\n");
635   return constants[no];
636 }