~ubuntu-branches/ubuntu/oneiric/gnupg2/oneiric-updates

« back to all changes in this revision

Viewing changes to mpi/mpiutil.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* mpiutil.ac  -  Utility functions for MPI
2
 
 * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3
 
 *
4
 
 * This file is part of GnuPG.
5
 
 *
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.
10
 
 *
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.
15
 
 *
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
19
 
 */
20
 
 
21
 
#include <config.h>
22
 
#include <stdio.h>
23
 
#include <stdlib.h>
24
 
#include <string.h>
25
 
#include <assert.h>
26
 
 
27
 
#include "mpi.h"
28
 
#include "mpi-internal.h"
29
 
#include "memory.h"
30
 
#include "util.h"
31
 
 
32
 
 
33
 
#ifdef M_DEBUG
34
 
  #undef mpi_alloc
35
 
  #undef mpi_alloc_secure
36
 
  #undef mpi_free
37
 
#endif
38
 
 
39
 
/****************
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).
43
 
 *
44
 
 *        But mpi_alloc is used in a lot of places :-)
45
 
 */
46
 
MPI
47
 
#ifdef M_DEBUG
48
 
mpi_debug_alloc( unsigned nlimbs, const char *info )
49
 
#else
50
 
mpi_alloc( unsigned nlimbs )
51
 
#endif
52
 
{
53
 
    MPI a;
54
 
 
55
 
    if( DBG_MEMORY )
56
 
        log_debug("mpi_alloc(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
57
 
  #ifdef M_DEBUG
58
 
    a = m_debug_alloc( sizeof *a, info );
59
 
    a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 0, info ) : NULL;
60
 
  #else
61
 
    a = m_alloc( sizeof *a );
62
 
    a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
63
 
  #endif
64
 
    a->alloced = nlimbs;
65
 
    a->nlimbs = 0;
66
 
    a->sign = 0;
67
 
    a->flags = 0;
68
 
    a->nbits = 0;
69
 
    return a;
70
 
}
71
 
 
72
 
void
73
 
mpi_m_check( MPI a )
74
 
{
75
 
    m_check(a);
76
 
    m_check(a->d);
77
 
}
78
 
 
79
 
MPI
80
 
#ifdef M_DEBUG
81
 
mpi_debug_alloc_secure( unsigned nlimbs, const char *info )
82
 
#else
83
 
mpi_alloc_secure( unsigned nlimbs )
84
 
#endif
85
 
{
86
 
    MPI a;
87
 
 
88
 
    if( DBG_MEMORY )
89
 
        log_debug("mpi_alloc_secure(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
90
 
  #ifdef M_DEBUG
91
 
    a = m_debug_alloc( sizeof *a, info );
92
 
    a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 1, info ) : NULL;
93
 
  #else
94
 
    a = m_alloc( sizeof *a );
95
 
    a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
96
 
  #endif
97
 
    a->alloced = nlimbs;
98
 
    a->flags = 1;
99
 
    a->nlimbs = 0;
100
 
    a->sign = 0;
101
 
    a->nbits = 0;
102
 
    return a;
103
 
}
104
 
 
105
 
 
106
 
#if 0
107
 
static void *unused_limbs_5;
108
 
static void *unused_limbs_32;
109
 
static void *unused_limbs_64;
110
 
#endif
111
 
 
112
 
mpi_ptr_t
113
 
#ifdef M_DEBUG
114
 
mpi_debug_alloc_limb_space( unsigned nlimbs, int secure, const char *info )
115
 
#else
116
 
mpi_alloc_limb_space( unsigned nlimbs, int secure )
117
 
#endif
118
 
{
119
 
    size_t len = nlimbs * sizeof(mpi_limb_t);
120
 
    mpi_ptr_t p;
121
 
 
122
 
    if( DBG_MEMORY )
123
 
        log_debug("mpi_alloc_limb_space(%u)\n", (unsigned)len*8 );
124
 
  #if 0
125
 
    if( !secure ) {
126
 
        if( nlimbs == 5 && unused_limbs_5 ) {  /* DSA 160 bits */
127
 
            p = unused_limbs_5;
128
 
            unused_limbs_5 = *p;
129
 
            return p;
130
 
        }
131
 
        else if( nlimbs == 32 && unused_limbs_32 ) {  /* DSA 1024 bits */
132
 
            p = unused_limbs_32;
133
 
            unused_limbs_32 = *p;
134
 
            return p;
135
 
        }
136
 
        else if( nlimbs == 64 && unused_limbs_64 ) {  /* DSA 2*1024 bits */
137
 
            p = unused_limbs_64;
138
 
            unused_limbs_64 = *p;
139
 
            return p;
140
 
        }
141
 
    }
142
 
  #endif
143
 
 
144
 
  #ifdef M_DEBUG
145
 
    p = secure? m_debug_alloc_secure(len, info):m_debug_alloc( len, info );
146
 
  #else
147
 
    p = secure? m_alloc_secure( len ):m_alloc( len );
148
 
  #endif
149
 
 
150
 
    return p;
151
 
}
152
 
 
153
 
void
154
 
#ifdef M_DEBUG
155
 
mpi_debug_free_limb_space( mpi_ptr_t a, const char *info )
156
 
#else
157
 
mpi_free_limb_space( mpi_ptr_t a )
158
 
#endif
159
 
{
160
 
    if( !a )
161
 
        return;
162
 
    if( DBG_MEMORY )
163
 
        log_debug("mpi_free_limb_space of size %lu\n", (ulong)m_size(a)*8 );
164
 
 
165
 
  #if 0
166
 
    if( !m_is_secure(a) ) {
167
 
        size_t nlimbs = m_size(a) / 4 ;
168
 
        void *p = a;
169
 
 
170
 
        if( nlimbs == 5 ) {  /* DSA 160 bits */
171
 
            *a = unused_limbs_5;
172
 
            unused_limbs_5 = a;
173
 
            return;
174
 
        }
175
 
        else if( nlimbs == 32 ) {  /* DSA 1024 bits */
176
 
            *a = unused_limbs_32;
177
 
            unused_limbs_32 = a;
178
 
            return;
179
 
        }
180
 
        else if( nlimbs == 64 ) {  /* DSA 2*1024 bits */
181
 
            *a = unused_limbs_64;
182
 
            unused_limbs_64 = a;
183
 
            return;
184
 
        }
185
 
    }
186
 
  #endif
187
 
 
188
 
 
189
 
    m_free(a);
190
 
}
191
 
 
192
 
 
193
 
void
194
 
mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs )
195
 
{
196
 
    mpi_free_limb_space(a->d);
197
 
    a->d = ap;
198
 
    a->alloced = nlimbs;
199
 
}
200
 
 
201
 
 
202
 
 
203
 
/****************
204
 
 * Resize the array of A to NLIMBS. the additional space is cleared
205
 
 * (set to 0) [done by m_realloc()]
206
 
 */
207
 
void
208
 
#ifdef M_DEBUG
209
 
mpi_debug_resize( MPI a, unsigned nlimbs, const char *info )
210
 
#else
211
 
mpi_resize( MPI a, unsigned nlimbs )
212
 
#endif
213
 
{
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
220
 
     */
221
 
  #ifdef M_DEBUG
222
 
    if( a->d )
223
 
        a->d = m_debug_realloc(a->d, nlimbs * sizeof(mpi_limb_t), info );
224
 
    else
225
 
        a->d = m_debug_alloc_clear( nlimbs * sizeof(mpi_limb_t), info );
226
 
  #else
227
 
    if( a->d )
228
 
        a->d = m_realloc(a->d, nlimbs * sizeof(mpi_limb_t) );
229
 
    else
230
 
        a->d = m_alloc_clear( nlimbs * sizeof(mpi_limb_t) );
231
 
  #endif
232
 
    a->alloced = nlimbs;
233
 
}
234
 
 
235
 
void
236
 
mpi_clear( MPI a )
237
 
{
238
 
    a->nlimbs = 0;
239
 
    a->nbits = 0;
240
 
    a->flags = 0;
241
 
}
242
 
 
243
 
 
244
 
void
245
 
#ifdef M_DEBUG
246
 
mpi_debug_free( MPI a, const char *info )
247
 
#else
248
 
mpi_free( MPI a )
249
 
#endif
250
 
{
251
 
    if( !a )
252
 
        return;
253
 
    if( DBG_MEMORY )
254
 
        log_debug("mpi_free\n" );
255
 
    if( a->flags & 4 )
256
 
        m_free( a->d );
257
 
    else {
258
 
      #ifdef M_DEBUG
259
 
        mpi_debug_free_limb_space(a->d, info);
260
 
      #else
261
 
        mpi_free_limb_space(a->d);
262
 
      #endif
263
 
    }
264
 
    if( a->flags & ~7 )
265
 
        log_bug("invalid flag value in mpi\n");
266
 
    m_free(a);
267
 
}
268
 
 
269
 
 
270
 
void
271
 
mpi_set_secure( MPI a )
272
 
{
273
 
    mpi_ptr_t ap, bp;
274
 
 
275
 
    if( (a->flags & 1) )
276
 
        return;
277
 
    a->flags |= 1;
278
 
    ap = a->d;
279
 
    if( !a->nlimbs ) {
280
 
        assert(!ap);
281
 
        return;
282
 
    }
283
 
  #ifdef M_DEBUG
284
 
    bp = mpi_debug_alloc_limb_space( a->nlimbs, 1, "set_secure" );
285
 
  #else
286
 
    bp = mpi_alloc_limb_space( a->nlimbs, 1 );
287
 
  #endif
288
 
    MPN_COPY( bp, ap, a->nlimbs );
289
 
    a->d = bp;
290
 
  #ifdef M_DEBUG
291
 
    mpi_debug_free_limb_space(ap, "set_secure");
292
 
  #else
293
 
    mpi_free_limb_space(ap);
294
 
  #endif
295
 
}
296
 
 
297
 
 
298
 
MPI
299
 
mpi_set_opaque( MPI a, void *p, int len )
300
 
{
301
 
    if( !a ) {
302
 
      #ifdef M_DEBUG
303
 
        a = mpi_debug_alloc(0,"alloc_opaque");
304
 
      #else
305
 
        a = mpi_alloc(0);
306
 
      #endif
307
 
    }
308
 
 
309
 
    if( a->flags & 4 )
310
 
        m_free( a->d );
311
 
    else {
312
 
      #ifdef M_DEBUG
313
 
        mpi_debug_free_limb_space(a->d, "alloc_opaque");
314
 
      #else
315
 
        mpi_free_limb_space(a->d);
316
 
      #endif
317
 
    }
318
 
 
319
 
    a->d = p;
320
 
    a->alloced = 0;
321
 
    a->nlimbs = 0;
322
 
    a->nbits = len;
323
 
    a->flags = 4;
324
 
    return a;
325
 
}
326
 
 
327
 
 
328
 
void *
329
 
mpi_get_opaque( MPI a, int *len )
330
 
{
331
 
    if( !(a->flags & 4) )
332
 
        log_bug("mpi_get_opaque on normal mpi\n");
333
 
    if( len )
334
 
        *len = a->nbits;
335
 
    return a->d;
336
 
}
337
 
 
338
 
 
339
 
/****************
340
 
 * Note: This copy function should not interpret the MPI
341
 
 *       but copy it transparently.
342
 
 */
343
 
MPI
344
 
#ifdef M_DEBUG
345
 
mpi_debug_copy( MPI a, const char *info )
346
 
#else
347
 
mpi_copy( MPI a )
348
 
#endif
349
 
{
350
 
    int i;
351
 
    MPI b;
352
 
 
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 );
358
 
    }
359
 
    else if( a ) {
360
 
      #ifdef M_DEBUG
361
 
        b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
362
 
                            : mpi_debug_alloc( a->nlimbs, info );
363
 
      #else
364
 
        b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
365
 
                            : mpi_alloc( a->nlimbs );
366
 
      #endif
367
 
        b->nlimbs = a->nlimbs;
368
 
        b->sign = a->sign;
369
 
        b->flags  = a->flags;
370
 
        b->nbits = a->nbits;
371
 
        for(i=0; i < b->nlimbs; i++ )
372
 
            b->d[i] = a->d[i];
373
 
    }
374
 
    else
375
 
        b = NULL;
376
 
    return b;
377
 
}
378
 
 
379
 
 
380
 
/****************
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.
384
 
 */
385
 
MPI
386
 
#ifdef M_DEBUG
387
 
mpi_debug_alloc_like( MPI a, const char *info )
388
 
#else
389
 
mpi_alloc_like( MPI a )
390
 
#endif
391
 
{
392
 
    MPI b;
393
 
 
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 );
399
 
    }
400
 
    else if( a ) {
401
 
      #ifdef M_DEBUG
402
 
        b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
403
 
                            : mpi_debug_alloc( a->nlimbs, info );
404
 
      #else
405
 
        b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
406
 
                            : mpi_alloc( a->nlimbs );
407
 
      #endif
408
 
        b->nlimbs = 0;
409
 
        b->sign = 0;
410
 
        b->flags = a->flags;
411
 
        b->nbits = 0;
412
 
    }
413
 
    else
414
 
        b = NULL;
415
 
    return b;
416
 
}
417
 
 
418
 
 
419
 
void
420
 
mpi_set( MPI w, MPI u)
421
 
{
422
 
    mpi_ptr_t wp, up;
423
 
    mpi_size_t usize = u->nlimbs;
424
 
    int usign = u->sign;
425
 
 
426
 
    RESIZE_IF_NEEDED(w, usize);
427
 
    wp = w->d;
428
 
    up = u->d;
429
 
    MPN_COPY( wp, up, usize );
430
 
    w->nlimbs = usize;
431
 
    w->nbits = u->nbits;
432
 
    w->flags = u->flags;
433
 
    w->sign = usign;
434
 
}
435
 
 
436
 
 
437
 
void
438
 
mpi_set_ui( MPI w, unsigned long u)
439
 
{
440
 
    RESIZE_IF_NEEDED(w, 1);
441
 
    w->d[0] = u;
442
 
    w->nlimbs = u? 1:0;
443
 
    w->sign = 0;
444
 
    w->nbits = 0;
445
 
    w->flags = 0;
446
 
}
447
 
 
448
 
 
449
 
MPI
450
 
mpi_alloc_set_ui( unsigned long u)
451
 
{
452
 
  #ifdef M_DEBUG
453
 
    MPI w = mpi_debug_alloc(1,"alloc_set_ui");
454
 
  #else
455
 
    MPI w = mpi_alloc(1);
456
 
  #endif
457
 
    w->d[0] = u;
458
 
    w->nlimbs = u? 1:0;
459
 
    w->sign = 0;
460
 
    return w;
461
 
}
462
 
 
463
 
 
464
 
void
465
 
mpi_swap( MPI a, MPI b)
466
 
{
467
 
    struct gcry_mpi tmp;
468
 
 
469
 
    tmp = *a; *a = *b; *b = tmp;
470
 
}
471