Coverage Report

Created: 2022-12-08 06:10

/src/libgcrypt/mpi/mpiutil.c
Line
Count
Source (jump to first uncovered line)
1
/* mpiutil.ac  -  Utility functions for MPI
2
 * Copyright (C) 1998, 2000, 2001, 2002, 2003,
3
 *               2007  Free Software Foundation, Inc.
4
 * Copyright (C) 2013  g10 Code GmbH
5
 *
6
 * This file is part of Libgcrypt.
7
 *
8
 * Libgcrypt is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as
10
 * published by the Free Software Foundation; either version 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
13
 * Libgcrypt is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include <config.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
27
#include "g10lib.h"
28
#include "mpi-internal.h"
29
#include "mod-source-info.h"
30
31
32
#if SIZEOF_UNSIGNED_INT == 2
33
# define MY_UINT_MAX 0xffff
34
/* (visual check:      0123 ) */
35
#elif SIZEOF_UNSIGNED_INT == 4
36
0
# define MY_UINT_MAX 0xffffffff
37
/* (visual check:      01234567 ) */
38
#elif SIZEOF_UNSIGNED_INT == 8
39
# define MY_UINT_MAX 0xffffffffffffffff
40
/* (visual check:      0123456789abcdef ) */
41
#else
42
# error Need MY_UINT_MAX for this limb size
43
#endif
44
45
46
/* Constants allocated right away at startup.  */
47
static gcry_mpi_t constants[MPI_NUMBER_OF_CONSTANTS];
48
49
/* These variables are used to generate masks from conditional operation
50
 * flag parameters.  Use of volatile prevents compiler optimizations from
51
 * converting AND-masking to conditional branches.  */
52
static volatile mpi_limb_t vzero = 0;
53
static volatile mpi_limb_t vone = 1;
54
55
56
const char *
57
_gcry_mpi_get_hw_config (void)
58
0
{
59
0
  return mod_source_info + 1;
60
0
}
61
62
63
/* Initialize the MPI subsystem.  This is called early and allows to
64
   do some initialization without taking care of threading issues.  */
65
gcry_err_code_t
66
_gcry_mpi_init (void)
67
4
{
68
4
  int idx;
69
4
  unsigned long value;
70
71
28
  for (idx=0; idx < MPI_NUMBER_OF_CONSTANTS; idx++)
72
24
    {
73
24
      switch (idx)
74
24
        {
75
4
        case MPI_C_ZERO:  value = 0; break;
76
4
        case MPI_C_ONE:   value = 1; break;
77
4
        case MPI_C_TWO:   value = 2; break;
78
4
        case MPI_C_THREE: value = 3; break;
79
4
        case MPI_C_FOUR:  value = 4; break;
80
4
        case MPI_C_EIGHT: value = 8; break;
81
0
        default: log_bug ("invalid mpi_const selector %d\n", idx);
82
24
        }
83
24
      constants[idx] = mpi_alloc_set_ui (value);
84
24
      constants[idx]->flags = (16|32);
85
24
    }
86
87
4
  return 0;
88
4
}
89
90
91
/****************
92
 * Note:  It was a bad idea to use the number of limbs to allocate
93
 *    because on a alpha the limbs are large but we normally need
94
 *    integers of n bits - So we should change this to bits (or bytes).
95
 *
96
 *    But mpi_alloc is used in a lot of places :-(.  New code
97
 *    should use mpi_new.
98
 */
99
gcry_mpi_t
100
_gcry_mpi_alloc( unsigned nlimbs )
101
6.62M
{
102
6.62M
    gcry_mpi_t a;
103
104
6.62M
    a = xmalloc( sizeof *a );
105
6.62M
    a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
106
6.62M
    a->alloced = nlimbs;
107
6.62M
    a->nlimbs = 0;
108
6.62M
    a->sign = 0;
109
6.62M
    a->flags = 0;
110
6.62M
    return a;
111
6.62M
}
112
113
gcry_mpi_t
114
_gcry_mpi_alloc_secure( unsigned nlimbs )
115
0
{
116
0
    gcry_mpi_t a;
117
118
0
    a = xmalloc( sizeof *a );
119
0
    a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
120
0
    a->alloced = nlimbs;
121
0
    a->flags = 1;
122
0
    a->nlimbs = 0;
123
0
    a->sign = 0;
124
0
    return a;
125
0
}
126
127
128
129
mpi_ptr_t
130
_gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
131
22.9M
{
132
22.9M
    mpi_ptr_t p;
133
22.9M
    size_t len;
134
135
22.9M
    len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
136
22.9M
    p = secure ? xmalloc_secure (len) : xmalloc (len);
137
22.9M
    if (! nlimbs)
138
489
      *p = 0;
139
140
22.9M
    return p;
141
22.9M
}
142
143
void
144
_gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
145
23.6M
{
146
23.6M
  if (a)
147
23.0M
    {
148
23.0M
      size_t len = nlimbs * sizeof(mpi_limb_t);
149
150
      /* If we have information on the number of allocated limbs, we
151
         better wipe that space out.  This is a failsafe feature if
152
         secure memory has been disabled or was not properly
153
         implemented in user provided allocation functions. */
154
23.0M
      if (len)
155
23.0M
        wipememory (a, len);
156
23.0M
      xfree(a);
157
23.0M
    }
158
23.6M
}
159
160
161
void
162
_gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
163
52.6k
{
164
52.6k
  _gcry_mpi_free_limb_space (a->d, a->alloced);
165
52.6k
  a->d = ap;
166
52.6k
  a->alloced = nlimbs;
167
52.6k
}
168
169
170
171
/****************
172
 * Resize the array of A to NLIMBS. The additional space is cleared
173
 * (set to 0).
174
 */
175
void
176
_gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
177
17.8M
{
178
17.8M
  size_t i;
179
180
17.8M
  if (nlimbs <= a->alloced)
181
17.5M
    {
182
      /* We only need to clear the new space (this is a nop if the
183
         limb space is already of the correct size. */
184
76.2M
      for (i=a->nlimbs; i < a->alloced; i++)
185
58.6M
        a->d[i] = 0;
186
17.5M
      return;
187
17.5M
    }
188
189
  /* Actually resize the limb space.  */
190
300k
  if (a->d)
191
137k
    {
192
137k
      a->d = xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
193
625k
      for (i=a->nlimbs; i < nlimbs; i++)
194
487k
        a->d[i] = 0;
195
137k
    }
196
162k
  else
197
162k
    {
198
162k
      if (a->flags & 1)
199
  /* Secure memory is wanted.  */
200
0
  a->d = xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
201
162k
      else
202
  /* Standard memory.  */
203
162k
  a->d = xcalloc (nlimbs , sizeof (mpi_limb_t));
204
162k
    }
205
300k
  a->alloced = nlimbs;
206
300k
}
207
208
void
209
_gcry_mpi_clear( gcry_mpi_t a )
210
0
{
211
0
  if (mpi_is_immutable (a))
212
0
    {
213
0
      mpi_immutable_failed ();
214
0
      return;
215
0
    }
216
0
  a->nlimbs = 0;
217
0
  a->flags = 0;
218
0
}
219
220
221
void
222
_gcry_mpi_free( gcry_mpi_t a )
223
14.5M
{
224
14.5M
  if (!a )
225
7.89M
    return;
226
6.62M
  if ((a->flags & 32))
227
0
  {
228
0
#if GPGRT_VERSION_NUMBER >= 0x011600  /* 1.22 */
229
0
    gpgrt_annotate_leaked_object(a);
230
0
#endif
231
0
    return; /* Never release a constant. */
232
0
  }
233
6.62M
  if ((a->flags & 4))
234
292k
    xfree( a->d );
235
6.32M
  else
236
6.32M
    {
237
6.32M
      _gcry_mpi_free_limb_space(a->d, a->alloced);
238
6.32M
    }
239
  /* Check that the flags makes sense.  We better allow for bit 1
240
     (value 2) for backward ABI compatibility.  */
241
6.62M
  if ((a->flags & ~(1|2|4|16
242
6.62M
                    |GCRYMPI_FLAG_USER1
243
6.62M
                    |GCRYMPI_FLAG_USER2
244
6.62M
                    |GCRYMPI_FLAG_USER3
245
6.62M
                    |GCRYMPI_FLAG_USER4)))
246
0
    log_bug("invalid flag value in mpi_free\n");
247
6.62M
  xfree (a);
248
6.62M
}
249
250
251
void
252
_gcry_mpi_immutable_failed (void)
253
0
{
254
0
  log_info ("Warning: trying to change an immutable MPI\n");
255
0
}
256
257
258
static void
259
mpi_set_secure( gcry_mpi_t a )
260
0
{
261
0
  mpi_ptr_t ap, bp;
262
263
0
  if ( (a->flags & 1) )
264
0
    return;
265
0
  a->flags |= 1;
266
0
  ap = a->d;
267
0
  if (!a->nlimbs)
268
0
    {
269
0
      gcry_assert (!ap);
270
0
      return;
271
0
    }
272
0
  bp = mpi_alloc_limb_space (a->alloced, 1);
273
0
  MPN_COPY( bp, ap, a->nlimbs );
274
0
  a->d = bp;
275
0
  _gcry_mpi_free_limb_space (ap, a->alloced);
276
0
}
277
278
279
gcry_mpi_t
280
_gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
281
293k
{
282
293k
  if (!a)
283
275k
    a = mpi_alloc(0);
284
285
293k
  if (mpi_is_immutable (a))
286
0
    {
287
0
      mpi_immutable_failed ();
288
0
      return a;
289
0
    }
290
291
293k
  if( a->flags & 4 )
292
944
    xfree (a->d);
293
292k
  else
294
292k
    _gcry_mpi_free_limb_space (a->d, a->alloced);
295
296
293k
  a->d = p;
297
293k
  a->alloced = 0;
298
293k
  a->nlimbs = 0;
299
293k
  a->sign  = nbits;
300
293k
  a->flags = 4 | (a->flags & (GCRYMPI_FLAG_USER1|GCRYMPI_FLAG_USER2
301
293k
                              |GCRYMPI_FLAG_USER3|GCRYMPI_FLAG_USER4));
302
293k
  if (_gcry_is_secure (a->d))
303
0
    a->flags |= 1;
304
293k
  return a;
305
293k
}
306
307
308
gcry_mpi_t
309
_gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits)
310
9.94k
{
311
9.94k
  void *d;
312
9.94k
  unsigned int n;
313
314
9.94k
  n = (nbits+7)/8;
315
9.94k
  d = _gcry_is_secure (p)? xtrymalloc_secure (n) : xtrymalloc (n);
316
9.94k
  if (!d)
317
0
    return NULL;
318
9.94k
  memcpy (d, p, n);
319
9.94k
  return mpi_set_opaque (a, d, nbits);
320
9.94k
}
321
322
323
void *
324
_gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
325
161k
{
326
161k
    if( !(a->flags & 4) )
327
0
  log_bug("mpi_get_opaque on normal mpi\n");
328
161k
    if( nbits )
329
160k
  *nbits = a->sign;
330
161k
    return a->d;
331
161k
}
332
333
334
void *
335
_gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits)
336
4.59k
{
337
4.59k
  const void *s;
338
4.59k
  void *d;
339
4.59k
  unsigned int n;
340
341
4.59k
  s = mpi_get_opaque (a, nbits);
342
4.59k
  if (!s && nbits)
343
0
    return NULL;
344
4.59k
  n = (*nbits+7)/8;
345
4.59k
  d = _gcry_is_secure (s)? xtrymalloc_secure (n) : xtrymalloc (n);
346
4.59k
  if (d)
347
4.59k
    memcpy (d, s, n);
348
4.59k
  return d;
349
4.59k
}
350
351
/****************
352
 * Note: This copy function should not interpret the MPI
353
 *   but copy it transparently.
354
 */
355
gcry_mpi_t
356
_gcry_mpi_copy (gcry_mpi_t a)
357
5.70M
{
358
5.70M
    int i;
359
5.70M
    gcry_mpi_t b;
360
361
5.70M
    if( a && (a->flags & 4) ) {
362
1.49k
        void *p = NULL;
363
1.49k
        if (a->sign) {
364
1.49k
            p = _gcry_is_secure(a->d)? xmalloc_secure ((a->sign+7)/8)
365
1.49k
                                     : xmalloc ((a->sign+7)/8);
366
1.49k
            if (a->d)
367
1.49k
                memcpy( p, a->d, (a->sign+7)/8 );
368
1.49k
        }
369
1.49k
        b = mpi_set_opaque( NULL, p, a->sign );
370
1.49k
        b->flags = a->flags;
371
1.49k
        b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
372
1.49k
    }
373
5.69M
    else if( a ) {
374
5.69M
  b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
375
5.69M
          : mpi_alloc( a->nlimbs );
376
5.69M
  b->nlimbs = a->nlimbs;
377
5.69M
  b->sign = a->sign;
378
5.69M
  b->flags  = a->flags;
379
5.69M
        b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
380
35.3M
  for(i=0; i < b->nlimbs; i++ )
381
29.6M
      b->d[i] = a->d[i];
382
5.69M
    }
383
487
    else
384
487
  b = NULL;
385
5.70M
    return b;
386
5.70M
}
387
388
389
/* Return true if A is negative.  */
390
int
391
_gcry_mpi_is_neg (gcry_mpi_t a)
392
0
{
393
0
  if (a->sign && _gcry_mpi_cmp_ui (a, 0))
394
0
    return 1;
395
0
  else
396
0
    return 0;
397
0
}
398
399
400
/* W = - U */
401
void
402
_gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u)
403
0
{
404
0
  if (w != u)
405
0
    mpi_set (w, u);
406
0
  else if (mpi_is_immutable (w))
407
0
    {
408
0
      mpi_immutable_failed ();
409
0
      return;
410
0
    }
411
412
0
  w->sign = !u->sign;
413
0
}
414
415
416
/* W = [W] */
417
void
418
_gcry_mpi_abs (gcry_mpi_t w)
419
0
{
420
0
  if (mpi_is_immutable (w))
421
0
    {
422
0
      mpi_immutable_failed ();
423
0
      return;
424
0
    }
425
426
0
  w->sign = 0;
427
0
}
428
429
430
/****************
431
 * This function allocates an MPI which is optimized to hold
432
 * a value as large as the one given in the argument and allocates it
433
 * with the same flags as A.
434
 */
435
gcry_mpi_t
436
_gcry_mpi_alloc_like( gcry_mpi_t a )
437
94.0k
{
438
94.0k
    gcry_mpi_t b;
439
440
94.0k
    if( a && (a->flags & 4) ) {
441
0
  int n = (a->sign+7)/8;
442
0
  void *p = _gcry_is_secure(a->d)? xtrymalloc_secure (n)
443
0
                                       : xtrymalloc (n);
444
0
  memcpy( p, a->d, n );
445
0
  b = mpi_set_opaque( NULL, p, a->sign );
446
0
    }
447
94.0k
    else if( a ) {
448
94.0k
  b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
449
94.0k
          : mpi_alloc( a->nlimbs );
450
94.0k
  b->nlimbs = 0;
451
94.0k
  b->sign = 0;
452
94.0k
  b->flags = a->flags;
453
94.0k
    }
454
0
    else
455
0
  b = NULL;
456
94.0k
    return b;
457
94.0k
}
458
459
460
/* Set U into W and release U.  If W is NULL only U will be released. */
461
void
462
_gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u)
463
21.9k
{
464
21.9k
  if (w)
465
21.9k
    {
466
21.9k
      if (mpi_is_immutable (w))
467
0
        {
468
0
          mpi_immutable_failed ();
469
0
          return;
470
0
        }
471
21.9k
      _gcry_mpi_assign_limb_space (w, u->d, u->alloced);
472
21.9k
      w->nlimbs = u->nlimbs;
473
21.9k
      w->sign   = u->sign;
474
21.9k
      w->flags  = u->flags;
475
21.9k
      u->alloced = 0;
476
21.9k
      u->nlimbs = 0;
477
21.9k
      u->d = NULL;
478
21.9k
    }
479
21.9k
  _gcry_mpi_free (u);
480
21.9k
}
481
482
483
gcry_mpi_t
484
_gcry_mpi_set (gcry_mpi_t w, gcry_mpi_t u)
485
1.44M
{
486
1.44M
  mpi_ptr_t wp, up;
487
1.44M
  mpi_size_t usize = u->nlimbs;
488
1.44M
  int usign = u->sign;
489
490
1.44M
  if (!w)
491
0
    w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
492
1.44M
  if (mpi_is_immutable (w))
493
0
    {
494
0
      mpi_immutable_failed ();
495
0
      return w;
496
0
    }
497
1.44M
  RESIZE_IF_NEEDED(w, usize);
498
1.44M
  wp = w->d;
499
1.44M
  up = u->d;
500
1.44M
  MPN_COPY( wp, up, usize );
501
1.44M
  w->nlimbs = usize;
502
1.44M
  w->flags = u->flags;
503
1.44M
  w->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
504
1.44M
  w->sign = usign;
505
1.44M
  return w;
506
1.44M
}
507
508
/****************
509
 * Set the value of W by the one of U, when SET is 1.
510
 * Leave the value when SET is 0.
511
 * This implementation should be constant-time regardless of SET.
512
 */
513
gcry_mpi_t
514
_gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u, unsigned long set)
515
16.4M
{
516
16.4M
  mpi_size_t i;
517
16.4M
  mpi_size_t nlimbs = u->alloced;
518
16.4M
  mpi_limb_t mask1 = vzero - set;
519
16.4M
  mpi_limb_t mask2 = set - vone;
520
16.4M
  mpi_limb_t xu;
521
16.4M
  mpi_limb_t xw;
522
16.4M
  mpi_limb_t *uu = u->d;
523
16.4M
  mpi_limb_t *uw = w->d;
524
525
16.4M
  if (w->alloced != u->alloced)
526
0
    log_bug ("mpi_set_cond: different sizes\n");
527
528
127M
  for (i = 0; i < nlimbs; i++)
529
110M
    {
530
110M
      xu = uu[i];
531
110M
      xw = uw[i];
532
110M
      uw[i] = (xw & mask2) | (xu & mask1);
533
110M
    }
534
535
16.4M
  xu = u->nlimbs;
536
16.4M
  xw = w->nlimbs;
537
16.4M
  w->nlimbs = (xw & mask2) | (xu & mask1);
538
539
16.4M
  xu = u->sign;
540
16.4M
  xw = w->sign;
541
16.4M
  w->sign = (xw & mask2) | (xu & mask1);
542
16.4M
  return w;
543
16.4M
}
544
545
546
gcry_mpi_t
547
_gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
548
37.5k
{
549
37.5k
  if (!w)
550
1
    w = _gcry_mpi_alloc (1);
551
  /* FIXME: If U is 0 we have no need to resize and thus possible
552
     allocating the the limbs. */
553
37.5k
  if (mpi_is_immutable (w))
554
0
    {
555
0
      mpi_immutable_failed ();
556
0
      return w;
557
0
    }
558
37.5k
  RESIZE_IF_NEEDED(w, 1);
559
37.5k
  w->d[0] = u;
560
37.5k
  w->nlimbs = u? 1:0;
561
37.5k
  w->sign = 0;
562
37.5k
  w->flags = 0;
563
37.5k
  return w;
564
37.5k
}
565
566
/* If U is non-negative and small enough store it as an unsigned int
567
 * at W.  If the value does not fit into an unsigned int or is
568
 * negative return GPG_ERR_ERANGE.  Note that we return an unsigned
569
 * int so that the value can be used with the bit test functions; in
570
 * contrast the other _ui functions take an unsigned long so that on
571
 * some platforms they may accept a larger value.  On error the value
572
 * at W is not changed. */
573
gcry_err_code_t
574
_gcry_mpi_get_ui (unsigned int *w, gcry_mpi_t u)
575
0
{
576
0
  mpi_limb_t x;
577
578
0
  if (u->nlimbs > 1 || u->sign)
579
0
    return GPG_ERR_ERANGE;
580
581
0
  x = (u->nlimbs == 1) ? u->d[0] : 0;
582
0
  if (sizeof (x) > sizeof (unsigned int) && x > MY_UINT_MAX)
583
0
    return GPG_ERR_ERANGE;
584
585
0
  *w = x;
586
0
  return 0;
587
0
}
588
589
590
gcry_mpi_t
591
_gcry_mpi_alloc_set_ui( unsigned long u)
592
10.0k
{
593
10.0k
    gcry_mpi_t w = mpi_alloc(1);
594
10.0k
    w->d[0] = u;
595
10.0k
    w->nlimbs = u? 1:0;
596
10.0k
    w->sign = 0;
597
10.0k
    return w;
598
10.0k
}
599
600
void
601
_gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
602
0
{
603
0
    struct gcry_mpi tmp;
604
605
0
    tmp = *a; *a = *b; *b = tmp;
606
0
}
607
608
609
/****************
610
 * Swap the value of A and B, when SWAP is 1.
611
 * Leave the value when SWAP is 0.
612
 * This implementation should be constant-time regardless of SWAP.
613
 */
614
void
615
_gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap)
616
0
{
617
0
  mpi_size_t i;
618
0
  mpi_size_t nlimbs;
619
0
  mpi_limb_t mask1 = vzero - swap;
620
0
  mpi_limb_t mask2 = swap - vone;
621
0
  mpi_limb_t *ua = a->d;
622
0
  mpi_limb_t *ub = b->d;
623
0
  mpi_limb_t xa;
624
0
  mpi_limb_t xb;
625
626
0
  if (a->alloced > b->alloced)
627
0
    nlimbs = b->alloced;
628
0
  else
629
0
    nlimbs = a->alloced;
630
0
  if (a->nlimbs > nlimbs || b->nlimbs > nlimbs)
631
0
    log_bug ("mpi_swap_cond: different sizes\n");
632
633
0
  for (i = 0; i < nlimbs; i++)
634
0
    {
635
0
      xa = ua[i];
636
0
      xb = ub[i];
637
0
      ua[i] = (xa & mask2) | (xb & mask1);
638
0
      ub[i] = (xa & mask1) | (xb & mask2);
639
0
    }
640
641
0
  xa = a->nlimbs;
642
0
  xb = b->nlimbs;
643
0
  a->nlimbs = (xa & mask2) | (xb & mask1);
644
0
  b->nlimbs = (xa & mask1) | (xb & mask2);
645
646
0
  xa = a->sign;
647
0
  xb = b->sign;
648
0
  a->sign = (xa & mask2) | (xb & mask1);
649
0
  b->sign = (xa & mask1) | (xb & mask2);
650
0
}
651
652
653
/****************
654
 * Set bit N of A, when SET is 1.
655
 * This implementation should be constant-time regardless of SET.
656
 */
657
void
658
_gcry_mpi_set_bit_cond (gcry_mpi_t a, unsigned int n, unsigned long set)
659
0
{
660
0
  unsigned int limbno, bitno;
661
0
  mpi_limb_t set_the_bit = !!set;
662
663
0
  limbno = n / BITS_PER_MPI_LIMB;
664
0
  bitno  = n % BITS_PER_MPI_LIMB;
665
666
0
  a->d[limbno] |= (set_the_bit<<bitno);
667
0
}
668
669
670
gcry_mpi_t
671
_gcry_mpi_new (unsigned int nbits)
672
201k
{
673
201k
    return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
674
201k
                             / BITS_PER_MPI_LIMB );
675
201k
}
676
677
678
gcry_mpi_t
679
_gcry_mpi_snew (unsigned int nbits)
680
0
{
681
0
  return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
682
0
                                  / BITS_PER_MPI_LIMB );
683
0
}
684
685
void
686
_gcry_mpi_release( gcry_mpi_t a )
687
8.44M
{
688
8.44M
    _gcry_mpi_free( a );
689
8.44M
}
690
691
void
692
_gcry_mpi_randomize (gcry_mpi_t w,
693
                     unsigned int nbits, enum gcry_random_level level)
694
0
{
695
0
  unsigned char *p;
696
0
  size_t nbytes = (nbits+7)/8;
697
698
0
  if (mpi_is_immutable (w))
699
0
    {
700
0
      mpi_immutable_failed ();
701
0
      return;
702
0
    }
703
0
  if (level == GCRY_WEAK_RANDOM)
704
0
    {
705
0
      p = mpi_is_secure(w) ? xmalloc_secure (nbytes)
706
0
                           : xmalloc (nbytes);
707
0
      _gcry_create_nonce (p, nbytes);
708
0
    }
709
0
  else
710
0
    {
711
0
      p = mpi_is_secure(w) ? _gcry_random_bytes_secure (nbytes, level)
712
0
                           : _gcry_random_bytes (nbytes, level);
713
0
    }
714
0
  _gcry_mpi_set_buffer( w, p, nbytes, 0 );
715
0
  xfree (p);
716
0
}
717
718
719
void
720
_gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
721
64.6k
{
722
64.6k
  switch (flag)
723
64.6k
    {
724
0
    case GCRYMPI_FLAG_SECURE:     mpi_set_secure(a); break;
725
0
    case GCRYMPI_FLAG_CONST:      a->flags |= (16|32); break;
726
0
    case GCRYMPI_FLAG_IMMUTABLE:  a->flags |= 16; break;
727
728
11.1k
    case GCRYMPI_FLAG_USER1:
729
64.6k
    case GCRYMPI_FLAG_USER2:
730
64.6k
    case GCRYMPI_FLAG_USER3:
731
64.6k
    case GCRYMPI_FLAG_USER4:      a->flags |= flag; break;
732
733
0
    case GCRYMPI_FLAG_OPAQUE:
734
0
    default: log_bug("invalid flag value\n");
735
64.6k
    }
736
64.6k
}
737
738
void
739
_gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
740
0
{
741
0
  (void)a; /* Not yet used. */
742
743
0
  switch (flag)
744
0
    {
745
0
    case GCRYMPI_FLAG_IMMUTABLE:
746
0
      if (!(a->flags & 32))
747
0
        a->flags &= ~16;
748
0
      break;
749
750
0
    case GCRYMPI_FLAG_USER1:
751
0
    case GCRYMPI_FLAG_USER2:
752
0
    case GCRYMPI_FLAG_USER3:
753
0
    case GCRYMPI_FLAG_USER4:
754
0
      a->flags &= ~flag;
755
0
      break;
756
757
0
    case GCRYMPI_FLAG_CONST:
758
0
    case GCRYMPI_FLAG_SECURE:
759
0
    case GCRYMPI_FLAG_OPAQUE:
760
0
    default: log_bug("invalid flag value\n");
761
0
    }
762
0
}
763
764
int
765
_gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
766
629k
{
767
629k
  switch (flag)
768
629k
    {
769
72.1k
    case GCRYMPI_FLAG_SECURE:    return !!(a->flags & 1);
770
505k
    case GCRYMPI_FLAG_OPAQUE:    return !!(a->flags & 4);
771
0
    case GCRYMPI_FLAG_IMMUTABLE: return !!(a->flags & 16);
772
0
    case GCRYMPI_FLAG_CONST:     return !!(a->flags & 32);
773
0
    case GCRYMPI_FLAG_USER1:
774
51.2k
    case GCRYMPI_FLAG_USER2:
775
51.2k
    case GCRYMPI_FLAG_USER3:
776
51.2k
    case GCRYMPI_FLAG_USER4:     return !!(a->flags & flag);
777
0
    default: log_bug("invalid flag value\n");
778
629k
    }
779
  /*NOTREACHED*/
780
0
  return 0;
781
629k
}
782
783
784
/* Return a constant MPI descripbed by NO which is one of the
785
   MPI_C_xxx macros.  There is no need to copy this returned value; it
786
   may be used directly.  */
787
gcry_mpi_t
788
_gcry_mpi_const (enum gcry_mpi_constants no)
789
4.53M
{
790
4.53M
  if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS)
791
0
    log_bug("invalid mpi_const selector %d\n", no);
792
4.53M
  if (!constants[no])
793
0
    log_bug("MPI subsystem not initialized\n");
794
4.53M
  return constants[no];
795
4.53M
}