~ubuntu-branches/ubuntu/trusty/grub2/trusty

« back to all changes in this revision

Viewing changes to grub-core/lib/libgcrypt/mpi/mpiutil.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2014-01-16 15:18:04 UTC
  • mfrom: (17.6.38 experimental)
  • Revision ID: package-import@ubuntu.com-20140116151804-3foouk7fpqcq3sxx
Tags: 2.02~beta2-2
* Convert patch handling to git-dpm.
* Add bi-endian support to ELF parser (Tomohiro B Berry).
* Adjust restore_mkdevicemap.patch to mark get_kfreebsd_version as static,
  to appease "gcc -Werror=missing-prototypes".
* Cherry-pick from upstream:
  - Change grub-macbless' manual page section to 8.
* Install grub-glue-efi, grub-macbless, grub-render-label, and
  grub-syslinux2cfg.
* grub-shell: Pass -no-pad to xorriso when building floppy images.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* mpiutil.ac  -  Utility functions for MPI
 
2
 * Copyright (C) 1998, 2000, 2001, 2002, 2003,
 
3
 *               2007  Free Software Foundation, Inc.
 
4
 *
 
5
 * This file is part of Libgcrypt.
 
6
 *
 
7
 * Libgcrypt is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU Lesser General Public License as
 
9
 * published by the Free Software Foundation; either version 2.1 of
 
10
 * the License, or (at your option) any later version.
 
11
 *
 
12
 * Libgcrypt is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
 
19
 */
 
20
 
 
21
#include <config.h>
 
22
#include <stdio.h>
 
23
#include <stdlib.h>
 
24
#include <string.h>
 
25
 
 
26
#include "g10lib.h"
 
27
#include "mpi-internal.h"
 
28
#include "mod-source-info.h"
 
29
 
 
30
 
 
31
const char *
 
32
_gcry_mpi_get_hw_config (void)
 
33
{
 
34
  return mod_source_info + 1;
 
35
}
 
36
 
 
37
 
 
38
/****************
 
39
 * Note:  It was a bad idea to use the number of limbs to allocate
 
40
 *        because on a alpha the limbs are large but we normally need
 
41
 *        integers of n bits - So we should change this to bits (or bytes).
 
42
 *
 
43
 *        But mpi_alloc is used in a lot of places :-(.  New code
 
44
 *        should use mpi_new.
 
45
 */
 
46
gcry_mpi_t
 
47
_gcry_mpi_alloc( unsigned nlimbs )
 
48
{
 
49
    gcry_mpi_t a;
 
50
 
 
51
    a = gcry_xmalloc( sizeof *a );
 
52
    a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
 
53
    a->alloced = nlimbs;
 
54
    a->nlimbs = 0;
 
55
    a->sign = 0;
 
56
    a->flags = 0;
 
57
    return a;
 
58
}
 
59
 
 
60
void
 
61
_gcry_mpi_m_check( gcry_mpi_t a )
 
62
{
 
63
    _gcry_check_heap(a);
 
64
    _gcry_check_heap(a->d);
 
65
}
 
66
 
 
67
gcry_mpi_t
 
68
_gcry_mpi_alloc_secure( unsigned nlimbs )
 
69
{
 
70
    gcry_mpi_t a;
 
71
 
 
72
    a = gcry_xmalloc( sizeof *a );
 
73
    a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
 
74
    a->alloced = nlimbs;
 
75
    a->flags = 1;
 
76
    a->nlimbs = 0;
 
77
    a->sign = 0;
 
78
    return a;
 
79
}
 
80
 
 
81
 
 
82
 
 
83
mpi_ptr_t
 
84
_gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
 
85
{
 
86
    mpi_ptr_t p;
 
87
    size_t len;
 
88
 
 
89
    len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
 
90
    p = secure ? gcry_xmalloc_secure (len) : gcry_xmalloc (len);
 
91
    if (! nlimbs)
 
92
      *p = 0;
 
93
 
 
94
    return p;
 
95
}
 
96
 
 
97
void
 
98
_gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
 
99
{
 
100
  if (a)
 
101
    {
 
102
      size_t len = nlimbs * sizeof(mpi_limb_t);
 
103
 
 
104
      /* If we have information on the number of allocated limbs, we
 
105
         better wipe that space out.  This is a failsafe feature if
 
106
         secure memory has been disabled or was not properly
 
107
         implemented in user provided allocation functions. */
 
108
      if (len)
 
109
        wipememory (a, len);
 
110
      gcry_free(a);
 
111
    }
 
112
}
 
113
 
 
114
 
 
115
void
 
116
_gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
 
117
{
 
118
  _gcry_mpi_free_limb_space (a->d, a->alloced);
 
119
  a->d = ap;
 
120
  a->alloced = nlimbs;
 
121
}
 
122
 
 
123
 
 
124
 
 
125
/****************
 
126
 * Resize the array of A to NLIMBS. The additional space is cleared
 
127
 * (set to 0).
 
128
 */
 
129
void
 
130
_gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
 
131
{
 
132
  size_t i;
 
133
 
 
134
  if (nlimbs <= a->alloced)
 
135
    {
 
136
      /* We only need to clear the new space (this is a nop if the
 
137
         limb space is already of the correct size. */
 
138
      for (i=a->nlimbs; i < a->alloced; i++)
 
139
        a->d[i] = 0;
 
140
      return;
 
141
    }
 
142
 
 
143
  /* Actually resize the limb space.  */
 
144
  if (a->d)
 
145
    {
 
146
      a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
 
147
      for (i=a->alloced; i < nlimbs; i++)
 
148
        a->d[i] = 0;
 
149
    }
 
150
  else
 
151
    {
 
152
      if (a->flags & 1)
 
153
        /* Secure memory is wanted.  */
 
154
        a->d = gcry_xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
 
155
      else
 
156
        /* Standard memory.  */
 
157
        a->d = gcry_xcalloc (nlimbs , sizeof (mpi_limb_t));
 
158
    }
 
159
  a->alloced = nlimbs;
 
160
}
 
161
 
 
162
void
 
163
_gcry_mpi_clear( gcry_mpi_t a )
 
164
{
 
165
    a->nlimbs = 0;
 
166
    a->flags = 0;
 
167
}
 
168
 
 
169
 
 
170
void
 
171
_gcry_mpi_free( gcry_mpi_t a )
 
172
{
 
173
  if (!a )
 
174
    return;
 
175
  if ((a->flags & 4))
 
176
    gcry_free( a->d );
 
177
  else
 
178
    {
 
179
      _gcry_mpi_free_limb_space(a->d, a->alloced);
 
180
    }
 
181
  if ((a->flags & ~7))
 
182
    log_bug("invalid flag value in mpi\n");
 
183
  gcry_free(a);
 
184
}
 
185
 
 
186
static void
 
187
mpi_set_secure( gcry_mpi_t a )
 
188
{
 
189
  mpi_ptr_t ap, bp;
 
190
 
 
191
  if ( (a->flags & 1) )
 
192
    return;
 
193
  a->flags |= 1;
 
194
  ap = a->d;
 
195
  if (!a->nlimbs)
 
196
    {
 
197
      gcry_assert (!ap);
 
198
      return;
 
199
    }
 
200
  bp = mpi_alloc_limb_space (a->nlimbs, 1);
 
201
  MPN_COPY( bp, ap, a->nlimbs );
 
202
  a->d = bp;
 
203
  _gcry_mpi_free_limb_space (ap, a->alloced);
 
204
}
 
205
 
 
206
 
 
207
gcry_mpi_t
 
208
gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits )
 
209
{
 
210
  if (!a)
 
211
    a = mpi_alloc(0);
 
212
 
 
213
  if( a->flags & 4 )
 
214
    gcry_free( a->d );
 
215
  else
 
216
    _gcry_mpi_free_limb_space (a->d, a->alloced);
 
217
 
 
218
  a->d = p;
 
219
  a->alloced = 0;
 
220
  a->nlimbs = 0;
 
221
  a->sign  = nbits;
 
222
  a->flags = 4;
 
223
  return a;
 
224
}
 
225
 
 
226
 
 
227
void *
 
228
gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits )
 
229
{
 
230
    if( !(a->flags & 4) )
 
231
        log_bug("mpi_get_opaque on normal mpi\n");
 
232
    if( nbits )
 
233
        *nbits = a->sign;
 
234
    return a->d;
 
235
}
 
236
 
 
237
 
 
238
/****************
 
239
 * Note: This copy function should not interpret the MPI
 
240
 *       but copy it transparently.
 
241
 */
 
242
gcry_mpi_t
 
243
gcry_mpi_copy( gcry_mpi_t a )
 
244
{
 
245
    int i;
 
246
    gcry_mpi_t b;
 
247
 
 
248
    if( a && (a->flags & 4) ) {
 
249
        void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 )
 
250
                                     : gcry_xmalloc( (a->sign+7)/8 );
 
251
        memcpy( p, a->d, (a->sign+7)/8 );
 
252
        b = gcry_mpi_set_opaque( NULL, p, a->sign );
 
253
    }
 
254
    else if( a ) {
 
255
        b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
 
256
                            : mpi_alloc( a->nlimbs );
 
257
        b->nlimbs = a->nlimbs;
 
258
        b->sign = a->sign;
 
259
        b->flags  = a->flags;
 
260
        for(i=0; i < b->nlimbs; i++ )
 
261
            b->d[i] = a->d[i];
 
262
    }
 
263
    else
 
264
        b = NULL;
 
265
    return b;
 
266
}
 
267
 
 
268
 
 
269
/****************
 
270
 * This function allocates an MPI which is optimized to hold
 
271
 * a value as large as the one given in the argument and allocates it
 
272
 * with the same flags as A.
 
273
 */
 
274
gcry_mpi_t
 
275
_gcry_mpi_alloc_like( gcry_mpi_t a )
 
276
{
 
277
    gcry_mpi_t b;
 
278
 
 
279
    if( a && (a->flags & 4) ) {
 
280
        int n = (a->sign+7)/8;
 
281
        void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n )
 
282
                                     : gcry_malloc( n );
 
283
        memcpy( p, a->d, n );
 
284
        b = gcry_mpi_set_opaque( NULL, p, a->sign );
 
285
    }
 
286
    else if( a ) {
 
287
        b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
 
288
                            : mpi_alloc( a->nlimbs );
 
289
        b->nlimbs = 0;
 
290
        b->sign = 0;
 
291
        b->flags = a->flags;
 
292
    }
 
293
    else
 
294
        b = NULL;
 
295
    return b;
 
296
}
 
297
 
 
298
 
 
299
gcry_mpi_t
 
300
gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u)
 
301
{
 
302
  mpi_ptr_t wp, up;
 
303
  mpi_size_t usize = u->nlimbs;
 
304
  int usign = u->sign;
 
305
 
 
306
  if (!w)
 
307
    w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
 
308
  RESIZE_IF_NEEDED(w, usize);
 
309
  wp = w->d;
 
310
  up = u->d;
 
311
  MPN_COPY( wp, up, usize );
 
312
  w->nlimbs = usize;
 
313
  w->flags = u->flags;
 
314
  w->sign = usign;
 
315
  return w;
 
316
}
 
317
 
 
318
 
 
319
gcry_mpi_t
 
320
gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u)
 
321
{
 
322
  if (!w)
 
323
    w = _gcry_mpi_alloc (1);
 
324
  /* FIXME: If U is 0 we have no need to resize and thus possible
 
325
     allocating the the limbs. */
 
326
  RESIZE_IF_NEEDED(w, 1);
 
327
  w->d[0] = u;
 
328
  w->nlimbs = u? 1:0;
 
329
  w->sign = 0;
 
330
  w->flags = 0;
 
331
  return w;
 
332
}
 
333
 
 
334
gcry_err_code_t
 
335
_gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
 
336
{
 
337
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
 
338
  unsigned long x = 0;
 
339
 
 
340
  if (w->nlimbs > 1)
 
341
    err = GPG_ERR_TOO_LARGE;
 
342
  else if (w->nlimbs == 1)
 
343
    x = w->d[0];
 
344
  else
 
345
    x = 0;
 
346
 
 
347
  if (! err)
 
348
    *u = x;
 
349
 
 
350
  return err;
 
351
}
 
352
 
 
353
gcry_error_t
 
354
gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
 
355
{
 
356
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
 
357
 
 
358
  err = _gcry_mpi_get_ui (w, u);
 
359
 
 
360
  return gcry_error (err);
 
361
}
 
362
 
 
363
gcry_mpi_t
 
364
_gcry_mpi_alloc_set_ui( unsigned long u)
 
365
{
 
366
    gcry_mpi_t w = mpi_alloc(1);
 
367
    w->d[0] = u;
 
368
    w->nlimbs = u? 1:0;
 
369
    w->sign = 0;
 
370
    return w;
 
371
}
 
372
 
 
373
void
 
374
gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
 
375
{
 
376
    struct gcry_mpi tmp;
 
377
 
 
378
    tmp = *a; *a = *b; *b = tmp;
 
379
}
 
380
 
 
381
 
 
382
gcry_mpi_t
 
383
gcry_mpi_new( unsigned int nbits )
 
384
{
 
385
    return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
 
386
                             / BITS_PER_MPI_LIMB );
 
387
}
 
388
 
 
389
 
 
390
gcry_mpi_t
 
391
gcry_mpi_snew( unsigned int nbits )
 
392
{
 
393
  return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
 
394
                                  / BITS_PER_MPI_LIMB );
 
395
}
 
396
 
 
397
void
 
398
gcry_mpi_release( gcry_mpi_t a )
 
399
{
 
400
    _gcry_mpi_free( a );
 
401
}
 
402
 
 
403
void
 
404
gcry_mpi_randomize( gcry_mpi_t w,
 
405
                    unsigned int nbits, enum gcry_random_level level )
 
406
{
 
407
  unsigned char *p;
 
408
  size_t nbytes = (nbits+7)/8;
 
409
 
 
410
  if (level == GCRY_WEAK_RANDOM)
 
411
    {
 
412
      p = mpi_is_secure(w) ? gcry_xmalloc_secure (nbytes)
 
413
                           : gcry_xmalloc (nbytes);
 
414
      gcry_create_nonce (p, nbytes);
 
415
    }
 
416
  else
 
417
    {
 
418
      p = mpi_is_secure(w) ? gcry_random_bytes_secure (nbytes, level)
 
419
                           : gcry_random_bytes (nbytes, level);
 
420
    }
 
421
  _gcry_mpi_set_buffer( w, p, nbytes, 0 );
 
422
  gcry_free (p);
 
423
}
 
424
 
 
425
 
 
426
void
 
427
gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
 
428
{
 
429
    switch( flag ) {
 
430
      case GCRYMPI_FLAG_SECURE:  mpi_set_secure(a); break;
 
431
      case GCRYMPI_FLAG_OPAQUE:
 
432
      default: log_bug("invalid flag value\n");
 
433
    }
 
434
}
 
435
 
 
436
void
 
437
gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
 
438
{
 
439
  (void)a; /* Not yet used. */
 
440
 
 
441
  switch (flag)
 
442
    {
 
443
    case GCRYMPI_FLAG_SECURE:
 
444
    case GCRYMPI_FLAG_OPAQUE:
 
445
    default: log_bug("invalid flag value\n");
 
446
    }
 
447
}
 
448
 
 
449
int
 
450
gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
 
451
{
 
452
  switch (flag)
 
453
    {
 
454
    case GCRYMPI_FLAG_SECURE: return (a->flags & 1);
 
455
    case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4);
 
456
    default: log_bug("invalid flag value\n");
 
457
    }
 
458
  /*NOTREACHED*/
 
459
  return 0;
 
460
}