1
/* mpiutil.ac - Utility functions for MPI
2
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
4
* This file is part of GnuPG.
6
* GnuPG is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* GnuPG is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
28
#include "mpi-internal.h"
35
#undef mpi_alloc_secure
40
* Note: It was a bad idea to use the number of limbs to allocate
41
* because on a alpha the limbs are large but we normally need
42
* integers of n bits - So we should chnage this to bits (or bytes).
44
* But mpi_alloc is used in a lot of places :-)
48
mpi_debug_alloc( unsigned nlimbs, const char *info )
50
mpi_alloc( unsigned nlimbs )
56
log_debug("mpi_alloc(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
58
a = m_debug_alloc( sizeof *a, info );
59
a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 0, info ) : NULL;
61
a = m_alloc( sizeof *a );
62
a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
81
mpi_debug_alloc_secure( unsigned nlimbs, const char *info )
83
mpi_alloc_secure( unsigned nlimbs )
89
log_debug("mpi_alloc_secure(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
91
a = m_debug_alloc( sizeof *a, info );
92
a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 1, info ) : NULL;
94
a = m_alloc( sizeof *a );
95
a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
107
static void *unused_limbs_5;
108
static void *unused_limbs_32;
109
static void *unused_limbs_64;
114
mpi_debug_alloc_limb_space( unsigned nlimbs, int secure, const char *info )
116
mpi_alloc_limb_space( unsigned nlimbs, int secure )
119
size_t len = nlimbs * sizeof(mpi_limb_t);
123
log_debug("mpi_alloc_limb_space(%u)\n", (unsigned)len*8 );
126
if( nlimbs == 5 && unused_limbs_5 ) { /* DSA 160 bits */
131
else if( nlimbs == 32 && unused_limbs_32 ) { /* DSA 1024 bits */
133
unused_limbs_32 = *p;
136
else if( nlimbs == 64 && unused_limbs_64 ) { /* DSA 2*1024 bits */
138
unused_limbs_64 = *p;
145
p = secure? m_debug_alloc_secure(len, info):m_debug_alloc( len, info );
147
p = secure? m_alloc_secure( len ):m_alloc( len );
155
mpi_debug_free_limb_space( mpi_ptr_t a, const char *info )
157
mpi_free_limb_space( mpi_ptr_t a )
163
log_debug("mpi_free_limb_space of size %lu\n", (ulong)m_size(a)*8 );
166
if( !m_is_secure(a) ) {
167
size_t nlimbs = m_size(a) / 4 ;
170
if( nlimbs == 5 ) { /* DSA 160 bits */
175
else if( nlimbs == 32 ) { /* DSA 1024 bits */
176
*a = unused_limbs_32;
180
else if( nlimbs == 64 ) { /* DSA 2*1024 bits */
181
*a = unused_limbs_64;
194
mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs )
196
mpi_free_limb_space(a->d);
204
* Resize the array of A to NLIMBS. the additional space is cleared
205
* (set to 0) [done by m_realloc()]
209
mpi_debug_resize( MPI a, unsigned nlimbs, const char *info )
211
mpi_resize( MPI a, unsigned nlimbs )
214
if( nlimbs <= a->alloced )
215
return; /* no need to do it */
216
/* Note: a->secure is not used - instead the realloc functions
217
* take care of it. Maybe we should drop a->secure completely
218
* and rely on a mpi_is_secure function, which would be
219
* a wrapper around m_is_secure
223
a->d = m_debug_realloc(a->d, nlimbs * sizeof(mpi_limb_t), info );
225
a->d = m_debug_alloc_clear( nlimbs * sizeof(mpi_limb_t), info );
228
a->d = m_realloc(a->d, nlimbs * sizeof(mpi_limb_t) );
230
a->d = m_alloc_clear( nlimbs * sizeof(mpi_limb_t) );
246
mpi_debug_free( MPI a, const char *info )
254
log_debug("mpi_free\n" );
259
mpi_debug_free_limb_space(a->d, info);
261
mpi_free_limb_space(a->d);
265
log_bug("invalid flag value in mpi\n");
271
mpi_set_secure( MPI a )
284
bp = mpi_debug_alloc_limb_space( a->nlimbs, 1, "set_secure" );
286
bp = mpi_alloc_limb_space( a->nlimbs, 1 );
288
MPN_COPY( bp, ap, a->nlimbs );
291
mpi_debug_free_limb_space(ap, "set_secure");
293
mpi_free_limb_space(ap);
299
mpi_set_opaque( MPI a, void *p, int len )
303
a = mpi_debug_alloc(0,"alloc_opaque");
313
mpi_debug_free_limb_space(a->d, "alloc_opaque");
315
mpi_free_limb_space(a->d);
329
mpi_get_opaque( MPI a, int *len )
331
if( !(a->flags & 4) )
332
log_bug("mpi_get_opaque on normal mpi\n");
340
* Note: This copy function should not interpret the MPI
341
* but copy it transparently.
345
mpi_debug_copy( MPI a, const char *info )
353
if( a && (a->flags & 4) ) {
354
void *p = m_is_secure(a->d)? m_alloc_secure( a->nbits )
355
: m_alloc( a->nbits );
356
memcpy( p, a->d, a->nbits );
357
b = mpi_set_opaque( NULL, p, a->nbits );
361
b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
362
: mpi_debug_alloc( a->nlimbs, info );
364
b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
365
: mpi_alloc( a->nlimbs );
367
b->nlimbs = a->nlimbs;
371
for(i=0; i < b->nlimbs; i++ )
381
* This function allocates an MPI which is optimized to hold
382
* a value as large as the one given in the arhgument and allocates it
383
* with the same flags as A.
387
mpi_debug_alloc_like( MPI a, const char *info )
389
mpi_alloc_like( MPI a )
394
if( a && (a->flags & 4) ) {
395
void *p = m_is_secure(a->d)? m_alloc_secure( a->nbits )
396
: m_alloc( a->nbits );
397
memcpy( p, a->d, a->nbits );
398
b = mpi_set_opaque( NULL, p, a->nbits );
402
b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
403
: mpi_debug_alloc( a->nlimbs, info );
405
b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
406
: mpi_alloc( a->nlimbs );
420
mpi_set( MPI w, MPI u)
423
mpi_size_t usize = u->nlimbs;
426
RESIZE_IF_NEEDED(w, usize);
429
MPN_COPY( wp, up, usize );
438
mpi_set_ui( MPI w, unsigned long u)
440
RESIZE_IF_NEEDED(w, 1);
450
mpi_alloc_set_ui( unsigned long u)
453
MPI w = mpi_debug_alloc(1,"alloc_set_ui");
455
MPI w = mpi_alloc(1);
465
mpi_swap( MPI a, MPI b)
469
tmp = *a; *a = *b; *b = tmp;