Coverage Report

Created: 2024-11-21 07:03

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