LCOV - code coverage report
Current view: top level - mpi - mpiutil.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 240 327 73.4 %
Date: 2015-11-05 17:08:00 Functions: 33 38 86.8 %

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

Generated by: LCOV version 1.11