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