LCOV - code coverage report
Current view: top level - mpi - mpiutil.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 330 0.0 %
Date: 2016-12-15 12:59:22 Functions: 0 38 0.0 %

          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           0 : _gcry_mpi_get_hw_config (void)
      38             : {
      39           0 :   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           0 : _gcry_mpi_init (void)
      47             : {
      48             :   int idx;
      49             :   unsigned long value;
      50             : 
      51           0 :   for (idx=0; idx < MPI_NUMBER_OF_CONSTANTS; idx++)
      52             :     {
      53           0 :       switch (idx)
      54             :         {
      55           0 :         case MPI_C_ZERO:  value = 0; break;
      56           0 :         case MPI_C_ONE:   value = 1; break;
      57           0 :         case MPI_C_TWO:   value = 2; break;
      58           0 :         case MPI_C_THREE: value = 3; break;
      59           0 :         case MPI_C_FOUR:  value = 4; break;
      60           0 :         case MPI_C_EIGHT: value = 8; break;
      61           0 :         default: log_bug ("invalid mpi_const selector %d\n", idx);
      62             :         }
      63           0 :       constants[idx] = mpi_alloc_set_ui (value);
      64           0 :       constants[idx]->flags = (16|32);
      65             :     }
      66             : 
      67           0 :   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           0 : _gcry_mpi_alloc( unsigned nlimbs )
      81             : {
      82             :     gcry_mpi_t a;
      83             : 
      84           0 :     a = xmalloc( sizeof *a );
      85           0 :     a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
      86           0 :     a->alloced = nlimbs;
      87           0 :     a->nlimbs = 0;
      88           0 :     a->sign = 0;
      89           0 :     a->flags = 0;
      90           0 :     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           0 : _gcry_mpi_alloc_secure( unsigned nlimbs )
     102             : {
     103             :     gcry_mpi_t a;
     104             : 
     105           0 :     a = xmalloc( sizeof *a );
     106           0 :     a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
     107           0 :     a->alloced = nlimbs;
     108           0 :     a->flags = 1;
     109           0 :     a->nlimbs = 0;
     110           0 :     a->sign = 0;
     111           0 :     return a;
     112             : }
     113             : 
     114             : 
     115             : 
     116             : mpi_ptr_t
     117           0 : _gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
     118             : {
     119             :     mpi_ptr_t p;
     120             :     size_t len;
     121             : 
     122           0 :     len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
     123           0 :     p = secure ? xmalloc_secure (len) : xmalloc (len);
     124           0 :     if (! nlimbs)
     125           0 :       *p = 0;
     126             : 
     127           0 :     return p;
     128             : }
     129             : 
     130             : void
     131           0 : _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
     132             : {
     133           0 :   if (a)
     134             :     {
     135           0 :       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           0 :       if (len)
     142           0 :         wipememory (a, len);
     143           0 :       xfree(a);
     144             :     }
     145           0 : }
     146             : 
     147             : 
     148             : void
     149           0 : _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
     150             : {
     151           0 :   _gcry_mpi_free_limb_space (a->d, a->alloced);
     152           0 :   a->d = ap;
     153           0 :   a->alloced = nlimbs;
     154           0 : }
     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           0 : _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
     164             : {
     165             :   size_t i;
     166             : 
     167           0 :   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           0 :       for (i=a->nlimbs; i < a->alloced; i++)
     172           0 :         a->d[i] = 0;
     173           0 :       return;
     174             :     }
     175             : 
     176             :   /* Actually resize the limb space.  */
     177           0 :   if (a->d)
     178             :     {
     179           0 :       a->d = xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
     180           0 :       for (i=a->alloced; i < nlimbs; i++)
     181           0 :         a->d[i] = 0;
     182             :     }
     183             :   else
     184             :     {
     185           0 :       if (a->flags & 1)
     186             :         /* Secure memory is wanted.  */
     187           0 :         a->d = xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
     188             :       else
     189             :         /* Standard memory.  */
     190           0 :         a->d = xcalloc (nlimbs , sizeof (mpi_limb_t));
     191             :     }
     192           0 :   a->alloced = nlimbs;
     193             : }
     194             : 
     195             : void
     196           0 : _gcry_mpi_clear( gcry_mpi_t a )
     197             : {
     198           0 :   if (mpi_is_immutable (a))
     199             :     {
     200           0 :       mpi_immutable_failed ();
     201           0 :       return;
     202             :     }
     203           0 :   a->nlimbs = 0;
     204           0 :   a->flags = 0;
     205             : }
     206             : 
     207             : 
     208             : void
     209           0 : _gcry_mpi_free( gcry_mpi_t a )
     210             : {
     211           0 :   if (!a )
     212           0 :     return;
     213           0 :   if ((a->flags & 32))
     214             :   {
     215             : #if GPGRT_VERSION_NUMBER >= 0x011600  /* 1.22 */
     216           0 :     gpgrt_annotate_leaked_object(a);
     217             : #endif
     218           0 :     return; /* Never release a constant. */
     219             :   }
     220           0 :   if ((a->flags & 4))
     221           0 :     xfree( a->d );
     222             :   else
     223             :     {
     224           0 :       _gcry_mpi_free_limb_space(a->d, a->alloced);
     225             :     }
     226             :   /* Check that the flags makes sense.  We better allow for bit 1
     227             :      (value 2) for backward ABI compatibility.  */
     228           0 :   if ((a->flags & ~(1|2|4|16
     229             :                     |GCRYMPI_FLAG_USER1
     230             :                     |GCRYMPI_FLAG_USER2
     231             :                     |GCRYMPI_FLAG_USER3
     232             :                     |GCRYMPI_FLAG_USER4)))
     233           0 :     log_bug("invalid flag value in mpi_free\n");
     234           0 :   xfree (a);
     235             : }
     236             : 
     237             : 
     238             : void
     239           0 : _gcry_mpi_immutable_failed (void)
     240             : {
     241           0 :   log_info ("Warning: trying to change an immutable MPI\n");
     242           0 : }
     243             : 
     244             : 
     245             : static void
     246           0 : mpi_set_secure( gcry_mpi_t a )
     247             : {
     248             :   mpi_ptr_t ap, bp;
     249             : 
     250           0 :   if ( (a->flags & 1) )
     251           0 :     return;
     252           0 :   a->flags |= 1;
     253           0 :   ap = a->d;
     254           0 :   if (!a->nlimbs)
     255             :     {
     256           0 :       gcry_assert (!ap);
     257           0 :       return;
     258             :     }
     259           0 :   bp = mpi_alloc_limb_space (a->nlimbs, 1);
     260           0 :   MPN_COPY( bp, ap, a->nlimbs );
     261           0 :   a->d = bp;
     262           0 :   _gcry_mpi_free_limb_space (ap, a->alloced);
     263             : }
     264             : 
     265             : 
     266             : gcry_mpi_t
     267           0 : _gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
     268             : {
     269           0 :   if (!a)
     270           0 :     a = mpi_alloc(0);
     271             : 
     272           0 :   if (mpi_is_immutable (a))
     273             :     {
     274           0 :       mpi_immutable_failed ();
     275           0 :       return a;
     276             :     }
     277             : 
     278           0 :   if( a->flags & 4 )
     279           0 :     xfree (a->d);
     280             :   else
     281           0 :     _gcry_mpi_free_limb_space (a->d, a->alloced);
     282             : 
     283           0 :   a->d = p;
     284           0 :   a->alloced = 0;
     285           0 :   a->nlimbs = 0;
     286           0 :   a->sign  = nbits;
     287           0 :   a->flags = 4 | (a->flags & (GCRYMPI_FLAG_USER1|GCRYMPI_FLAG_USER2
     288             :                               |GCRYMPI_FLAG_USER3|GCRYMPI_FLAG_USER4));
     289           0 :   if (_gcry_is_secure (a->d))
     290           0 :     a->flags |= 1;
     291           0 :   return a;
     292             : }
     293             : 
     294             : 
     295             : gcry_mpi_t
     296           0 : _gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits)
     297             : {
     298             :   void *d;
     299             :   unsigned int n;
     300             : 
     301           0 :   n = (nbits+7)/8;
     302           0 :   d = _gcry_is_secure (p)? xtrymalloc_secure (n) : xtrymalloc (n);
     303           0 :   if (!d)
     304           0 :     return NULL;
     305           0 :   memcpy (d, p, n);
     306           0 :   return mpi_set_opaque (a, d, nbits);
     307             : }
     308             : 
     309             : 
     310             : void *
     311           0 : _gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
     312             : {
     313           0 :     if( !(a->flags & 4) )
     314           0 :         log_bug("mpi_get_opaque on normal mpi\n");
     315           0 :     if( nbits )
     316           0 :         *nbits = a->sign;
     317           0 :     return a->d;
     318             : }
     319             : 
     320             : 
     321             : void *
     322           0 : _gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits)
     323             : {
     324             :   const void *s;
     325             :   void *d;
     326             :   unsigned int n;
     327             : 
     328           0 :   s = mpi_get_opaque (a, nbits);
     329           0 :   if (!s && nbits)
     330           0 :     return NULL;
     331           0 :   n = (*nbits+7)/8;
     332           0 :   d = _gcry_is_secure (s)? xtrymalloc_secure (n) : xtrymalloc (n);
     333           0 :   if (d)
     334           0 :     memcpy (d, s, n);
     335           0 :   return d;
     336             : }
     337             : 
     338             : /****************
     339             :  * Note: This copy function should not interpret the MPI
     340             :  *       but copy it transparently.
     341             :  */
     342             : gcry_mpi_t
     343           0 : _gcry_mpi_copy (gcry_mpi_t a)
     344             : {
     345             :     int i;
     346             :     gcry_mpi_t b;
     347             : 
     348           0 :     if( a && (a->flags & 4) ) {
     349           0 :         void *p = _gcry_is_secure(a->d)? xmalloc_secure ((a->sign+7)/8)
     350           0 :                                        : xmalloc ((a->sign+7)/8);
     351           0 :         if (a->d)
     352           0 :           memcpy( p, a->d, (a->sign+7)/8 );
     353           0 :         b = mpi_set_opaque( NULL, p, a->sign );
     354           0 :         b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
     355             :     }
     356           0 :     else if( a ) {
     357           0 :         b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
     358           0 :                             : mpi_alloc( a->nlimbs );
     359           0 :         b->nlimbs = a->nlimbs;
     360           0 :         b->sign = a->sign;
     361           0 :         b->flags  = a->flags;
     362           0 :         b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
     363           0 :         for(i=0; i < b->nlimbs; i++ )
     364           0 :             b->d[i] = a->d[i];
     365             :     }
     366             :     else
     367           0 :         b = NULL;
     368           0 :     return b;
     369             : }
     370             : 
     371             : 
     372             : /* Return true if A is negative.  */
     373             : int
     374           0 : _gcry_mpi_is_neg (gcry_mpi_t a)
     375             : {
     376           0 :   if (a->sign && _gcry_mpi_cmp_ui (a, 0))
     377           0 :     return 1;
     378             :   else
     379           0 :     return 0;
     380             : }
     381             : 
     382             : 
     383             : /* W = - U */
     384             : void
     385           0 : _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u)
     386             : {
     387           0 :   if (w != u)
     388           0 :     mpi_set (w, u);
     389           0 :   else if (mpi_is_immutable (w))
     390             :     {
     391           0 :       mpi_immutable_failed ();
     392           0 :       return;
     393             :     }
     394             : 
     395           0 :   w->sign = !u->sign;
     396             : }
     397             : 
     398             : 
     399             : /* W = [W] */
     400             : void
     401           0 : _gcry_mpi_abs (gcry_mpi_t w)
     402             : {
     403           0 :   if (mpi_is_immutable (w))
     404             :     {
     405           0 :       mpi_immutable_failed ();
     406           0 :       return;
     407             :     }
     408             : 
     409           0 :   w->sign = 0;
     410             : }
     411             : 
     412             : 
     413             : /****************
     414             :  * This function allocates an MPI which is optimized to hold
     415             :  * a value as large as the one given in the argument and allocates it
     416             :  * with the same flags as A.
     417             :  */
     418             : gcry_mpi_t
     419           0 : _gcry_mpi_alloc_like( gcry_mpi_t a )
     420             : {
     421             :     gcry_mpi_t b;
     422             : 
     423           0 :     if( a && (a->flags & 4) ) {
     424           0 :         int n = (a->sign+7)/8;
     425           0 :         void *p = _gcry_is_secure(a->d)? xtrymalloc_secure (n)
     426           0 :                                        : xtrymalloc (n);
     427           0 :         memcpy( p, a->d, n );
     428           0 :         b = mpi_set_opaque( NULL, p, a->sign );
     429             :     }
     430           0 :     else if( a ) {
     431           0 :         b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
     432           0 :                             : mpi_alloc( a->nlimbs );
     433           0 :         b->nlimbs = 0;
     434           0 :         b->sign = 0;
     435           0 :         b->flags = a->flags;
     436             :     }
     437             :     else
     438           0 :         b = NULL;
     439           0 :     return b;
     440             : }
     441             : 
     442             : 
     443             : /* Set U into W and release U.  If W is NULL only U will be released. */
     444             : void
     445           0 : _gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u)
     446             : {
     447           0 :   if (w)
     448             :     {
     449           0 :       if (mpi_is_immutable (w))
     450             :         {
     451           0 :           mpi_immutable_failed ();
     452           0 :           return;
     453             :         }
     454           0 :       _gcry_mpi_assign_limb_space (w, u->d, u->alloced);
     455           0 :       w->nlimbs = u->nlimbs;
     456           0 :       w->sign   = u->sign;
     457           0 :       w->flags  = u->flags;
     458           0 :       u->alloced = 0;
     459           0 :       u->nlimbs = 0;
     460           0 :       u->d = NULL;
     461             :     }
     462           0 :   _gcry_mpi_free (u);
     463             : }
     464             : 
     465             : 
     466             : gcry_mpi_t
     467           0 : _gcry_mpi_set (gcry_mpi_t w, gcry_mpi_t u)
     468             : {
     469             :   mpi_ptr_t wp, up;
     470           0 :   mpi_size_t usize = u->nlimbs;
     471           0 :   int usign = u->sign;
     472             : 
     473           0 :   if (!w)
     474           0 :     w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
     475           0 :   if (mpi_is_immutable (w))
     476             :     {
     477           0 :       mpi_immutable_failed ();
     478           0 :       return w;
     479             :     }
     480           0 :   RESIZE_IF_NEEDED(w, usize);
     481           0 :   wp = w->d;
     482           0 :   up = u->d;
     483           0 :   MPN_COPY( wp, up, usize );
     484           0 :   w->nlimbs = usize;
     485           0 :   w->flags = u->flags;
     486           0 :   w->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
     487           0 :   w->sign = usign;
     488           0 :   return w;
     489             : }
     490             : 
     491             : /****************
     492             :  * Set the value of W by the one of U, when SET is 1.
     493             :  * Leave the value when SET is 0.
     494             :  * This implementation should be constant-time regardless of SET.
     495             :  */
     496             : gcry_mpi_t
     497           0 : _gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u, unsigned long set)
     498             : {
     499             :   mpi_size_t i;
     500           0 :   mpi_size_t nlimbs = u->alloced;
     501           0 :   mpi_limb_t mask = ((mpi_limb_t)0) - set;
     502             :   mpi_limb_t x;
     503             : 
     504           0 :   if (w->alloced != u->alloced)
     505           0 :     log_bug ("mpi_set_cond: different sizes\n");
     506             : 
     507           0 :   for (i = 0; i < nlimbs; i++)
     508             :     {
     509           0 :       x = mask & (w->d[i] ^ u->d[i]);
     510           0 :       w->d[i] = w->d[i] ^ x;
     511             :     }
     512             : 
     513           0 :   x = mask & (w->nlimbs ^ u->nlimbs);
     514           0 :   w->nlimbs = w->nlimbs ^ x;
     515             : 
     516           0 :   x = mask & (w->sign ^ u->sign);
     517           0 :   w->sign = w->sign ^ x;
     518           0 :   return w;
     519             : }
     520             : 
     521             : 
     522             : gcry_mpi_t
     523           0 : _gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
     524             : {
     525           0 :   if (!w)
     526           0 :     w = _gcry_mpi_alloc (1);
     527             :   /* FIXME: If U is 0 we have no need to resize and thus possible
     528             :      allocating the the limbs. */
     529           0 :   if (mpi_is_immutable (w))
     530             :     {
     531           0 :       mpi_immutable_failed ();
     532           0 :       return w;
     533             :     }
     534           0 :   RESIZE_IF_NEEDED(w, 1);
     535           0 :   w->d[0] = u;
     536           0 :   w->nlimbs = u? 1:0;
     537           0 :   w->sign = 0;
     538           0 :   w->flags = 0;
     539           0 :   return w;
     540             : }
     541             : 
     542             : gcry_err_code_t
     543           0 : _gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
     544             : {
     545           0 :   gcry_err_code_t err = GPG_ERR_NO_ERROR;
     546           0 :   unsigned long x = 0;
     547             : 
     548           0 :   if (w->nlimbs > 1)
     549           0 :     err = GPG_ERR_TOO_LARGE;
     550           0 :   else if (w->nlimbs == 1)
     551           0 :     x = w->d[0];
     552             :   else
     553           0 :     x = 0;
     554             : 
     555           0 :   if (! err)
     556           0 :     *u = x;
     557             : 
     558           0 :   return err;
     559             : }
     560             : 
     561             : 
     562             : gcry_mpi_t
     563           0 : _gcry_mpi_alloc_set_ui( unsigned long u)
     564             : {
     565           0 :     gcry_mpi_t w = mpi_alloc(1);
     566           0 :     w->d[0] = u;
     567           0 :     w->nlimbs = u? 1:0;
     568           0 :     w->sign = 0;
     569           0 :     return w;
     570             : }
     571             : 
     572             : void
     573           0 : _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
     574             : {
     575             :     struct gcry_mpi tmp;
     576             : 
     577           0 :     tmp = *a; *a = *b; *b = tmp;
     578           0 : }
     579             : 
     580             : 
     581             : /****************
     582             :  * Swap the value of A and B, when SWAP is 1.
     583             :  * Leave the value when SWAP is 0.
     584             :  * This implementation should be constant-time regardless of SWAP.
     585             :  */
     586             : void
     587           0 : _gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap)
     588             : {
     589             :   mpi_size_t i;
     590             :   mpi_size_t nlimbs;
     591           0 :   mpi_limb_t mask = ((mpi_limb_t)0) - swap;
     592             :   mpi_limb_t x;
     593             : 
     594           0 :   if (a->alloced > b->alloced)
     595           0 :     nlimbs = b->alloced;
     596             :   else
     597           0 :     nlimbs = a->alloced;
     598           0 :   if (a->nlimbs > nlimbs || b->nlimbs > nlimbs)
     599           0 :     log_bug ("mpi_swap_cond: different sizes\n");
     600             : 
     601           0 :   for (i = 0; i < nlimbs; i++)
     602             :     {
     603           0 :       x = mask & (a->d[i] ^ b->d[i]);
     604           0 :       a->d[i] = a->d[i] ^ x;
     605           0 :       b->d[i] = b->d[i] ^ x;
     606             :     }
     607             : 
     608           0 :   x = mask & (a->nlimbs ^ b->nlimbs);
     609           0 :   a->nlimbs = a->nlimbs ^ x;
     610           0 :   b->nlimbs = b->nlimbs ^ x;
     611             : 
     612           0 :   x = mask & (a->sign ^ b->sign);
     613           0 :   a->sign = a->sign ^ x;
     614           0 :   b->sign = b->sign ^ x;
     615           0 : }
     616             : 
     617             : 
     618             : gcry_mpi_t
     619           0 : _gcry_mpi_new (unsigned int nbits)
     620             : {
     621           0 :     return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
     622             :                              / BITS_PER_MPI_LIMB );
     623             : }
     624             : 
     625             : 
     626             : gcry_mpi_t
     627           0 : _gcry_mpi_snew (unsigned int nbits)
     628             : {
     629           0 :   return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
     630             :                                   / BITS_PER_MPI_LIMB );
     631             : }
     632             : 
     633             : void
     634           0 : _gcry_mpi_release( gcry_mpi_t a )
     635             : {
     636           0 :     _gcry_mpi_free( a );
     637           0 : }
     638             : 
     639             : void
     640           0 : _gcry_mpi_randomize (gcry_mpi_t w,
     641             :                      unsigned int nbits, enum gcry_random_level level)
     642             : {
     643             :   unsigned char *p;
     644           0 :   size_t nbytes = (nbits+7)/8;
     645             : 
     646           0 :   if (mpi_is_immutable (w))
     647             :     {
     648           0 :       mpi_immutable_failed ();
     649           0 :       return;
     650             :     }
     651           0 :   if (level == GCRY_WEAK_RANDOM)
     652             :     {
     653           0 :       p = mpi_is_secure(w) ? xmalloc_secure (nbytes)
     654             :                            : xmalloc (nbytes);
     655           0 :       _gcry_create_nonce (p, nbytes);
     656             :     }
     657             :   else
     658             :     {
     659           0 :       p = mpi_is_secure(w) ? _gcry_random_bytes_secure (nbytes, level)
     660             :                            : _gcry_random_bytes (nbytes, level);
     661             :     }
     662           0 :   _gcry_mpi_set_buffer( w, p, nbytes, 0 );
     663           0 :   xfree (p);
     664             : }
     665             : 
     666             : 
     667             : void
     668           0 : _gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
     669             : {
     670           0 :   switch (flag)
     671             :     {
     672           0 :     case GCRYMPI_FLAG_SECURE:     mpi_set_secure(a); break;
     673           0 :     case GCRYMPI_FLAG_CONST:      a->flags |= (16|32); break;
     674           0 :     case GCRYMPI_FLAG_IMMUTABLE:  a->flags |= 16; break;
     675             : 
     676             :     case GCRYMPI_FLAG_USER1:
     677             :     case GCRYMPI_FLAG_USER2:
     678             :     case GCRYMPI_FLAG_USER3:
     679           0 :     case GCRYMPI_FLAG_USER4:      a->flags |= flag; break;
     680             : 
     681             :     case GCRYMPI_FLAG_OPAQUE:
     682           0 :     default: log_bug("invalid flag value\n");
     683             :     }
     684           0 : }
     685             : 
     686             : void
     687           0 : _gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
     688             : {
     689             :   (void)a; /* Not yet used. */
     690             : 
     691           0 :   switch (flag)
     692             :     {
     693             :     case GCRYMPI_FLAG_IMMUTABLE:
     694           0 :       if (!(a->flags & 32))
     695           0 :         a->flags &= ~16;
     696           0 :       break;
     697             : 
     698             :     case GCRYMPI_FLAG_USER1:
     699             :     case GCRYMPI_FLAG_USER2:
     700             :     case GCRYMPI_FLAG_USER3:
     701             :     case GCRYMPI_FLAG_USER4:
     702           0 :       a->flags &= ~flag;
     703           0 :       break;
     704             : 
     705             :     case GCRYMPI_FLAG_CONST:
     706             :     case GCRYMPI_FLAG_SECURE:
     707             :     case GCRYMPI_FLAG_OPAQUE:
     708           0 :     default: log_bug("invalid flag value\n");
     709             :     }
     710           0 : }
     711             : 
     712             : int
     713           0 : _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
     714             : {
     715           0 :   switch (flag)
     716             :     {
     717           0 :     case GCRYMPI_FLAG_SECURE:    return !!(a->flags & 1);
     718           0 :     case GCRYMPI_FLAG_OPAQUE:    return !!(a->flags & 4);
     719           0 :     case GCRYMPI_FLAG_IMMUTABLE: return !!(a->flags & 16);
     720           0 :     case GCRYMPI_FLAG_CONST:     return !!(a->flags & 32);
     721             :     case GCRYMPI_FLAG_USER1:
     722             :     case GCRYMPI_FLAG_USER2:
     723             :     case GCRYMPI_FLAG_USER3:
     724           0 :     case GCRYMPI_FLAG_USER4:     return !!(a->flags & flag);
     725           0 :     default: log_bug("invalid flag value\n");
     726             :     }
     727             :   /*NOTREACHED*/
     728             :   return 0;
     729             : }
     730             : 
     731             : 
     732             : /* Return a constant MPI descripbed by NO which is one of the
     733             :    MPI_C_xxx macros.  There is no need to copy this returned value; it
     734             :    may be used directly.  */
     735             : gcry_mpi_t
     736           0 : _gcry_mpi_const (enum gcry_mpi_constants no)
     737             : {
     738           0 :   if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS)
     739           0 :     log_bug("invalid mpi_const selector %d\n", no);
     740           0 :   if (!constants[no])
     741           0 :     log_bug("MPI subsystem not initialized\n");
     742           0 :   return constants[no];
     743             : }

Generated by: LCOV version 1.12