-
+ 757F8A9FFA7640843ABC7A20EE7F0460FAE4CB11A2928963C85399B7EA7ABA3332F5C1574E86DAB4BBA8384E5BF3F95161C1D1E15DB7B85BB96F369F1E67F6FA
mpi/mpiutil.c
(0 . 0)(1 . 505)
10114 /* mpiutil.ac - Utility functions for MPI
10115 * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
10116 *
10117 * This file is part of GnuPG.
10118 *
10119 * GnuPG is free software; you can redistribute it and/or modify
10120 * it under the terms of the GNU General Public License as published by
10121 * the Free Software Foundation; either version 3 of the License, or
10122 * (at your option) any later version.
10123 *
10124 * GnuPG is distributed in the hope that it will be useful,
10125 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10126 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10127 * GNU General Public License for more details.
10128 *
10129 * You should have received a copy of the GNU General Public License
10130 * along with this program; if not, see <http://www.gnu.org/licenses/>.
10131 */
10132
10133 #include <config.h>
10134 #include <stdio.h>
10135 #include <stdlib.h>
10136 #include <string.h>
10137 #include <assert.h>
10138
10139 #include "mpi.h"
10140 #include "mpi-internal.h"
10141 #include "memory.h"
10142 #include "util.h"
10143
10144
10145 #ifdef M_DEBUG
10146 #undef mpi_alloc
10147 #undef mpi_alloc_secure
10148 #undef mpi_free
10149 #endif
10150
10151 /****************
10152 * Note: It was a bad idea to use the number of limbs to allocate
10153 * because on a alpha the limbs are large but we normally need
10154 * integers of n bits - So we should chnage this to bits (or bytes).
10155 *
10156 * But mpi_alloc is used in a lot of places :-)
10157 */
10158 MPI
10159 #ifdef M_DEBUG
10160 mpi_debug_alloc( unsigned nlimbs, const char *info )
10161 #else
10162 mpi_alloc( unsigned nlimbs )
10163 #endif
10164 {
10165 MPI a;
10166
10167 if( DBG_MEMORY )
10168 log_debug("mpi_alloc(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
10169 #ifdef M_DEBUG
10170 a = m_debug_alloc( sizeof *a, info );
10171 a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 0, info ) : NULL;
10172 #else
10173 a = xmalloc( sizeof *a );
10174 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
10175 #endif
10176 a->alloced = nlimbs;
10177 a->nlimbs = 0;
10178 a->sign = 0;
10179 a->flags = 0;
10180 a->nbits = 0;
10181 return a;
10182 }
10183
10184 void
10185 mpi_m_check( MPI a )
10186 {
10187 m_check(a);
10188 m_check(a->d);
10189 }
10190
10191 MPI
10192 #ifdef M_DEBUG
10193 mpi_debug_alloc_secure( unsigned nlimbs, const char *info )
10194 #else
10195 mpi_alloc_secure( unsigned nlimbs )
10196 #endif
10197 {
10198 MPI a;
10199
10200 if( DBG_MEMORY )
10201 log_debug("mpi_alloc_secure(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
10202 #ifdef M_DEBUG
10203 a = m_debug_alloc( sizeof *a, info );
10204 a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 1, info ) : NULL;
10205 #else
10206 a = xmalloc( sizeof *a );
10207 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
10208 #endif
10209 a->alloced = nlimbs;
10210 a->flags = 1;
10211 a->nlimbs = 0;
10212 a->sign = 0;
10213 a->nbits = 0;
10214 return a;
10215 }
10216
10217
10218 #if 0
10219 static void *unused_limbs_5;
10220 static void *unused_limbs_32;
10221 static void *unused_limbs_64;
10222 #endif
10223
10224 mpi_ptr_t
10225 #ifdef M_DEBUG
10226 mpi_debug_alloc_limb_space( unsigned nlimbs, int secure, const char *info )
10227 #else
10228 mpi_alloc_limb_space( unsigned nlimbs, int secure )
10229 #endif
10230 {
10231 size_t len = nlimbs * sizeof(mpi_limb_t);
10232 mpi_ptr_t p;
10233
10234 if( DBG_MEMORY )
10235 log_debug("mpi_alloc_limb_space(%u)\n", (unsigned)len*8 );
10236 #if 0
10237 if( !secure ) {
10238 if( nlimbs == 5 && unused_limbs_5 ) { /* DSA 160 bits */
10239 p = unused_limbs_5;
10240 unused_limbs_5 = *p;
10241 return p;
10242 }
10243 else if( nlimbs == 32 && unused_limbs_32 ) { /* DSA 1024 bits */
10244 p = unused_limbs_32;
10245 unused_limbs_32 = *p;
10246 return p;
10247 }
10248 else if( nlimbs == 64 && unused_limbs_64 ) { /* DSA 2*1024 bits */
10249 p = unused_limbs_64;
10250 unused_limbs_64 = *p;
10251 return p;
10252 }
10253 }
10254 #endif
10255
10256 #ifdef M_DEBUG
10257 p = secure? m_debug_alloc_secure(len, info):m_debug_alloc( len, info );
10258 #else
10259 p = secure? xmalloc_secure( len ):xmalloc( len );
10260 #endif
10261
10262 return p;
10263 }
10264
10265 void
10266 #ifdef M_DEBUG
10267 mpi_debug_free_limb_space( mpi_ptr_t a, const char *info )
10268 #else
10269 mpi_free_limb_space( mpi_ptr_t a )
10270 #endif
10271 {
10272 if( !a )
10273 return;
10274 if( DBG_MEMORY )
10275 log_debug("mpi_free_limb_space of size %lu\n", (ulong)m_size(a)*8 );
10276
10277 #if 0
10278 if( !m_is_secure(a) ) {
10279 size_t nlimbs = m_size(a) / 4 ;
10280 void *p = a;
10281
10282 if( nlimbs == 5 ) { /* DSA 160 bits */
10283 *a = unused_limbs_5;
10284 unused_limbs_5 = a;
10285 return;
10286 }
10287 else if( nlimbs == 32 ) { /* DSA 1024 bits */
10288 *a = unused_limbs_32;
10289 unused_limbs_32 = a;
10290 return;
10291 }
10292 else if( nlimbs == 64 ) { /* DSA 2*1024 bits */
10293 *a = unused_limbs_64;
10294 unused_limbs_64 = a;
10295 return;
10296 }
10297 }
10298 #endif
10299
10300 xfree(a);
10301 }
10302
10303
10304 void
10305 mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs )
10306 {
10307 mpi_free_limb_space(a->d);
10308 a->d = ap;
10309 a->alloced = nlimbs;
10310 }
10311
10312
10313
10314 /****************
10315 * Resize the array of A to NLIMBS. the additional space is cleared
10316 * (set to 0) [done by xrealloc()]
10317 */
10318 void
10319 #ifdef M_DEBUG
10320 mpi_debug_resize( MPI a, unsigned nlimbs, const char *info )
10321 #else
10322 mpi_resize( MPI a, unsigned nlimbs )
10323 #endif
10324 {
10325 if( nlimbs <= a->alloced )
10326 return; /* no need to do it */
10327 /* Note: a->secure is not used - instead the realloc functions
10328 * take care of it. Maybe we should drop a->secure completely
10329 * and rely on a mpi_is_secure function, which would be
10330 * a wrapper around m_is_secure
10331 */
10332 #ifdef M_DEBUG
10333 if( a->d )
10334 a->d = m_debug_realloc(a->d, nlimbs * sizeof(mpi_limb_t), info );
10335 else
10336 a->d = m_debug_alloc_clear( nlimbs * sizeof(mpi_limb_t), info );
10337 #else
10338 if( a->d )
10339 a->d = xrealloc(a->d, nlimbs * sizeof(mpi_limb_t) );
10340 else
10341 a->d = xmalloc_clear( nlimbs * sizeof(mpi_limb_t) );
10342 #endif
10343 a->alloced = nlimbs;
10344 }
10345
10346 void
10347 mpi_clear( MPI a )
10348 {
10349 a->nlimbs = 0;
10350 a->nbits = 0;
10351 a->flags = 0;
10352 }
10353
10354
10355 void
10356 #ifdef M_DEBUG
10357 mpi_debug_free( MPI a, const char *info )
10358 #else
10359 mpi_free( MPI a )
10360 #endif
10361 {
10362 if( !a )
10363 return;
10364 if( DBG_MEMORY )
10365 log_debug("mpi_free\n" );
10366 if( a->flags & 4 )
10367 xfree( a->d );
10368 else {
10369 #ifdef M_DEBUG
10370 mpi_debug_free_limb_space(a->d, info);
10371 #else
10372 mpi_free_limb_space(a->d);
10373 #endif
10374 }
10375 if( a->flags & ~7 )
10376 log_bug("invalid flag value in mpi\n");
10377 xfree(a);
10378 }
10379
10380
10381 void
10382 mpi_set_secure( MPI a )
10383 {
10384 mpi_ptr_t ap, bp;
10385
10386 if( (a->flags & 1) )
10387 return;
10388 a->flags |= 1;
10389 ap = a->d;
10390 if( !a->nlimbs ) {
10391 assert(!ap);
10392 return;
10393 }
10394 #ifdef M_DEBUG
10395 bp = mpi_debug_alloc_limb_space( a->nlimbs, 1, "set_secure" );
10396 #else
10397 bp = mpi_alloc_limb_space( a->nlimbs, 1 );
10398 #endif
10399 MPN_COPY( bp, ap, a->nlimbs );
10400 a->d = bp;
10401 #ifdef M_DEBUG
10402 mpi_debug_free_limb_space(ap, "set_secure");
10403 #else
10404 mpi_free_limb_space(ap);
10405 #endif
10406 }
10407
10408
10409 MPI
10410 mpi_set_opaque( MPI a, void *p, unsigned int len )
10411 {
10412 if( !a ) {
10413 #ifdef M_DEBUG
10414 a = mpi_debug_alloc(0,"alloc_opaque");
10415 #else
10416 a = mpi_alloc(0);
10417 #endif
10418 }
10419
10420 if( a->flags & 4 )
10421 xfree( a->d );
10422 else {
10423 #ifdef M_DEBUG
10424 mpi_debug_free_limb_space(a->d, "alloc_opaque");
10425 #else
10426 mpi_free_limb_space(a->d);
10427 #endif
10428 }
10429
10430 a->d = p;
10431 a->alloced = 0;
10432 a->nlimbs = 0;
10433 a->nbits = len;
10434 a->flags = 4;
10435 return a;
10436 }
10437
10438
10439 void *
10440 mpi_get_opaque( MPI a, unsigned int *len )
10441 {
10442 if( !(a->flags & 4) )
10443 log_bug("mpi_get_opaque on normal mpi\n");
10444 if( len )
10445 *len = a->nbits;
10446 return a->d;
10447 }
10448
10449
10450 /****************
10451 * Note: This copy function should not interpret the MPI
10452 * but copy it transparently.
10453 */
10454 MPI
10455 #ifdef M_DEBUG
10456 mpi_debug_copy( MPI a, const char *info )
10457 #else
10458 mpi_copy( MPI a )
10459 #endif
10460 {
10461 int i;
10462 MPI b;
10463
10464 if( a && (a->flags & 4) ) {
10465 void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
10466 : xmalloc( a->nbits );
10467 memcpy( p, a->d, a->nbits );
10468 b = mpi_set_opaque( NULL, p, a->nbits );
10469 }
10470 else if( a ) {
10471 #ifdef M_DEBUG
10472 b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
10473 : mpi_debug_alloc( a->nlimbs, info );
10474 #else
10475 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
10476 : mpi_alloc( a->nlimbs );
10477 #endif
10478 b->nlimbs = a->nlimbs;
10479 b->sign = a->sign;
10480 b->flags = a->flags;
10481 b->nbits = a->nbits;
10482 for(i=0; i < b->nlimbs; i++ )
10483 b->d[i] = a->d[i];
10484 }
10485 else
10486 b = NULL;
10487 return b;
10488 }
10489
10490
10491 /****************
10492 * This function allocates an MPI which is optimized to hold
10493 * a value as large as the one given in the argument and allocates it
10494 * with the same flags as A.
10495 */
10496 MPI
10497 #ifdef M_DEBUG
10498 mpi_debug_alloc_like( MPI a, const char *info )
10499 #else
10500 mpi_alloc_like( MPI a )
10501 #endif
10502 {
10503 MPI b;
10504
10505 if( a && (a->flags & 4) ) {
10506 void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
10507 : xmalloc( a->nbits );
10508 memcpy( p, a->d, a->nbits );
10509 b = mpi_set_opaque( NULL, p, a->nbits );
10510 }
10511 else if( a ) {
10512 #ifdef M_DEBUG
10513 b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
10514 : mpi_debug_alloc( a->nlimbs, info );
10515 #else
10516 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
10517 : mpi_alloc( a->nlimbs );
10518 #endif
10519 b->nlimbs = 0;
10520 b->sign = 0;
10521 b->flags = a->flags;
10522 b->nbits = 0;
10523 }
10524 else
10525 b = NULL;
10526 return b;
10527 }
10528
10529
10530 void
10531 mpi_set( MPI w, MPI u)
10532 {
10533 mpi_ptr_t wp, up;
10534 mpi_size_t usize = u->nlimbs;
10535 int usign = u->sign;
10536
10537 RESIZE_IF_NEEDED(w, usize);
10538 wp = w->d;
10539 up = u->d;
10540 MPN_COPY( wp, up, usize );
10541 w->nlimbs = usize;
10542 w->nbits = u->nbits;
10543 w->flags = u->flags;
10544 w->sign = usign;
10545 }
10546
10547
10548 void
10549 mpi_set_ui( MPI w, unsigned long u)
10550 {
10551 RESIZE_IF_NEEDED(w, 1);
10552 w->d[0] = u;
10553 w->nlimbs = u? 1:0;
10554 w->sign = 0;
10555 w->nbits = 0;
10556 w->flags = 0;
10557 }
10558
10559
10560 MPI
10561 mpi_alloc_set_ui( unsigned long u)
10562 {
10563 #ifdef M_DEBUG
10564 MPI w = mpi_debug_alloc(1,"alloc_set_ui");
10565 #else
10566 MPI w = mpi_alloc(1);
10567 #endif
10568 w->d[0] = u;
10569 w->nlimbs = u? 1:0;
10570 w->sign = 0;
10571 return w;
10572 }
10573
10574
10575 void
10576 mpi_swap( MPI a, MPI b)
10577 {
10578 struct gcry_mpi tmp;
10579
10580 tmp = *a; *a = *b; *b = tmp;
10581 }
10582
10583
10584 int
10585 mpi_get_nlimbs (MPI a)
10586 {
10587 return a->nlimbs;
10588 }
10589
10590
10591 int
10592 mpi_is_neg (MPI a)
10593 {
10594 return a->sign;
10595 }
10596
10597
10598 /* Return the number of limbs to store an MPI which is specified by
10599 the number of bytes to represent it. */
10600 unsigned int
10601 mpi_nlimb_hint_from_nbytes (unsigned int nbytes)
10602 {
10603 return (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
10604 }
10605
10606 /* Return the number of limbs to store an MPI which is specified by
10607 the number of bytes to represent it. */
10608 unsigned int
10609 mpi_nlimb_hint_from_nbits (unsigned int nbits)
10610 {
10611 return (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB;
10612 }
10613
10614 unsigned int
10615 mpi_get_flags (MPI a)
10616 {
10617 return a->flags;
10618 }