bn_lib.c 22.5 KB
Newer Older
R
Rich Salz 已提交
1
/*
2
 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
R
Rich Salz 已提交
5 6 7
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8 9
 */

10
#include <assert.h>
B
Bodo Möller 已提交
11
#include <limits.h>
12
#include "internal/cryptlib.h"
13
#include "bn_local.h"
14
#include <openssl/opensslconf.h>
15
#include "internal/constant_time.h"
16

17
/* This stuff appears to be completely unused, so is deprecated */
18
#if !OPENSSL_API_0_9_8
19 20
/*-
 * For a 32 bit machine
21 22 23 24 25 26 27 28
 * 2 -   4 ==  128
 * 3 -   8 ==  256
 * 4 -  16 ==  512
 * 5 -  32 == 1024
 * 6 -  64 == 2048
 * 7 - 128 == 4096
 * 8 - 256 == 8192
 */
29 30 31 32 33 34 35 36
static int bn_limit_bits = 0;
static int bn_limit_num = 8;    /* (1<<bn_limit_bits) */
static int bn_limit_bits_low = 0;
static int bn_limit_num_low = 8; /* (1<<bn_limit_bits_low) */
static int bn_limit_bits_high = 0;
static int bn_limit_num_high = 8; /* (1<<bn_limit_bits_high) */
static int bn_limit_bits_mont = 0;
static int bn_limit_num_mont = 8; /* (1<<bn_limit_bits_mont) */
37

U
Ulf Möller 已提交
38
void BN_set_params(int mult, int high, int low, int mont)
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
{
    if (mult >= 0) {
        if (mult > (int)(sizeof(int) * 8) - 1)
            mult = sizeof(int) * 8 - 1;
        bn_limit_bits = mult;
        bn_limit_num = 1 << mult;
    }
    if (high >= 0) {
        if (high > (int)(sizeof(int) * 8) - 1)
            high = sizeof(int) * 8 - 1;
        bn_limit_bits_high = high;
        bn_limit_num_high = 1 << high;
    }
    if (low >= 0) {
        if (low > (int)(sizeof(int) * 8) - 1)
            low = sizeof(int) * 8 - 1;
        bn_limit_bits_low = low;
        bn_limit_num_low = 1 << low;
    }
    if (mont >= 0) {
        if (mont > (int)(sizeof(int) * 8) - 1)
            mont = sizeof(int) * 8 - 1;
        bn_limit_bits_mont = mont;
        bn_limit_num_mont = 1 << mont;
    }
}
65

U
Ulf Möller 已提交
66
int BN_get_params(int which)
67 68
{
    if (which == 0)
K
KaoruToda 已提交
69
        return bn_limit_bits;
70
    else if (which == 1)
K
KaoruToda 已提交
71
        return bn_limit_bits_high;
72
    else if (which == 2)
K
KaoruToda 已提交
73
        return bn_limit_bits_low;
74
    else if (which == 3)
K
KaoruToda 已提交
75
        return bn_limit_bits_mont;
76
    else
K
KaoruToda 已提交
77
        return 0;
78
}
79
#endif
80

B
Bodo Möller 已提交
81
const BIGNUM *BN_value_one(void)
82 83 84 85
{
    static const BN_ULONG data_one = 1L;
    static const BIGNUM const_one =
        { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA };
86

K
KaoruToda 已提交
87
    return &const_one;
88
}
89

U
Ulf Möller 已提交
90
int BN_num_bits_word(BN_ULONG l)
91
{
92 93 94 95 96 97 98 99 100
    BN_ULONG x, mask;
    int bits = (l != 0);

#if BN_BITS2 > 32
    x = l >> 32;
    mask = (0 - x) & BN_MASK2;
    mask = (0 - (mask >> (BN_BITS2 - 1)));
    bits += 32 & mask;
    l ^= (x ^ l) & mask;
101
#endif
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132

    x = l >> 16;
    mask = (0 - x) & BN_MASK2;
    mask = (0 - (mask >> (BN_BITS2 - 1)));
    bits += 16 & mask;
    l ^= (x ^ l) & mask;

    x = l >> 8;
    mask = (0 - x) & BN_MASK2;
    mask = (0 - (mask >> (BN_BITS2 - 1)));
    bits += 8 & mask;
    l ^= (x ^ l) & mask;

    x = l >> 4;
    mask = (0 - x) & BN_MASK2;
    mask = (0 - (mask >> (BN_BITS2 - 1)));
    bits += 4 & mask;
    l ^= (x ^ l) & mask;

    x = l >> 2;
    mask = (0 - x) & BN_MASK2;
    mask = (0 - (mask >> (BN_BITS2 - 1)));
    bits += 2 & mask;
    l ^= (x ^ l) & mask;

    x = l >> 1;
    mask = (0 - x) & BN_MASK2;
    mask = (0 - (mask >> (BN_BITS2 - 1)));
    bits += 1 & mask;

    return bits;
133
}
134

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
/*
 * This function still leaks `a->dmax`: it's caller's responsibility to
 * expand the input `a` in advance to a public length.
 */
static ossl_inline
int bn_num_bits_consttime(const BIGNUM *a)
{
    int j, ret;
    unsigned int mask, past_i;
    int i = a->top - 1;
    bn_check_top(a);

    for (j = 0, past_i = 0, ret = 0; j < a->dmax; j++) {
        mask = constant_time_eq_int(i, j); /* 0xff..ff if i==j, 0x0 otherwise */

        ret += BN_BITS2 & (~mask & ~past_i);
        ret += BN_num_bits_word(a->d[j]) & mask;

        past_i |= mask; /* past_i will become 0xff..ff after i==j */
    }

    /*
     * if BN_is_zero(a) => i is -1 and ret contains garbage, so we mask the
     * final result.
     */
    mask = ~(constant_time_eq_int(i, ((int)-1)));

    return ret & mask;
}

165
int BN_num_bits(const BIGNUM *a)
166 167 168
{
    int i = a->top - 1;
    bn_check_top(a);
169

170 171 172 173 174 175 176 177 178 179 180 181 182
    if (a->flags & BN_FLG_CONSTTIME) {
        /*
         * We assume that BIGNUMs flagged as CONSTTIME have also been expanded
         * so that a->dmax is not leaking secret information.
         *
         * In other words, it's the caller's responsibility to ensure `a` has
         * been preallocated in advance to a public length if we hit this
         * branch.
         *
         */
        return bn_num_bits_consttime(a);
    }

183 184
    if (BN_is_zero(a))
        return 0;
185

186 187
    return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
}
188

P
Pauli 已提交
189
static void bn_free_d(BIGNUM *a, int clear)
R
Rich Salz 已提交
190
{
F
FdaSilvaYY 已提交
191
    if (BN_get_flags(a, BN_FLG_SECURE))
P
Pauli 已提交
192 193 194
        OPENSSL_secure_clear_free(a->d, a->dmax * sizeof(a->d[0]));
    else if (clear != 0)
        OPENSSL_clear_free(a->d, a->dmax * sizeof(a->d[0]));
R
Rich Salz 已提交
195 196 197 198 199
    else
        OPENSSL_free(a->d);
}


U
Ulf Möller 已提交
200
void BN_clear_free(BIGNUM *a)
201 202 203
{
    if (a == NULL)
        return;
P
Pauli 已提交
204 205
    if (a->d != NULL && !BN_get_flags(a, BN_FLG_STATIC_DATA))
        bn_free_d(a, 1);
206 207
    if (BN_get_flags(a, BN_FLG_MALLOCED)) {
        OPENSSL_cleanse(a, sizeof(*a));
208
        OPENSSL_free(a);
209
    }
210
}
211

U
Ulf Möller 已提交
212
void BN_free(BIGNUM *a)
213 214 215
{
    if (a == NULL)
        return;
R
Rich Salz 已提交
216
    if (!BN_get_flags(a, BN_FLG_STATIC_DATA))
P
Pauli 已提交
217
        bn_free_d(a, 0);
218 219 220
    if (a->flags & BN_FLG_MALLOCED)
        OPENSSL_free(a);
}
221

R
Rich Salz 已提交
222
void bn_init(BIGNUM *a)
223
{
R
Rich Salz 已提交
224 225 226
    static BIGNUM nilbn;

    *a = nilbn;
227 228
    bn_check_top(a);
}
229

U
Ulf Möller 已提交
230
BIGNUM *BN_new(void)
231 232 233
{
    BIGNUM *ret;

R
Rich Salz 已提交
234
    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
235
        BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE);
K
KaoruToda 已提交
236
        return NULL;
237 238 239
    }
    ret->flags = BN_FLG_MALLOCED;
    bn_check_top(ret);
K
KaoruToda 已提交
240
    return ret;
241
}
242

R
Rich Salz 已提交
243 244 245
 BIGNUM *BN_secure_new(void)
 {
     BIGNUM *ret = BN_new();
246
     if (ret != NULL)
R
Rich Salz 已提交
247
         ret->flags |= BN_FLG_SECURE;
K
KaoruToda 已提交
248
     return ret;
R
Rich Salz 已提交
249 250
 }

251
/* This is used by bn_expand2() */
252
/* The caller MUST check that words > b->dmax before calling this */
253
static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
254
{
255
    BN_ULONG *a = NULL;
256 257 258 259 260 261 262

    if (words > (INT_MAX / (4 * BN_BITS2))) {
        BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
        return NULL;
    }
    if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
        BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
K
KaoruToda 已提交
263
        return NULL;
264
    }
F
FdaSilvaYY 已提交
265
    if (BN_get_flags(b, BN_FLG_SECURE))
266
        a = OPENSSL_secure_zalloc(words * sizeof(*a));
R
Rich Salz 已提交
267
    else
268 269
        a = OPENSSL_zalloc(words * sizeof(*a));
    if (a == NULL) {
270
        BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
K
KaoruToda 已提交
271
        return NULL;
272
    }
273

274
    assert(b->top <= words);
275 276
    if (b->top > 0)
        memcpy(a, b->d, sizeof(*a) * b->top);
277

278
    return a;
279 280 281 282 283 284 285 286 287
}

/*
 * This is an internal function that should not be used in applications. It
 * ensures that 'b' has enough room for a 'words' word number and initialises
 * any unused part of b->d with leading zeros. It is mostly used by the
 * various BIGNUM routines. If there is an error, NULL is returned. If not,
 * 'b' is returned.
 */
288

289
BIGNUM *bn_expand2(BIGNUM *b, int words)
290 291 292 293 294
{
    if (words > b->dmax) {
        BN_ULONG *a = bn_expand_internal(b, words);
        if (!a)
            return NULL;
P
Pauli 已提交
295 296
        if (b->d != NULL)
            bn_free_d(b, 1);
297 298 299
        b->d = a;
        b->dmax = words;
    }
G
Geoff Thorpe 已提交
300

301 302
    return b;
}
303

304
BIGNUM *BN_dup(const BIGNUM *a)
305 306 307 308 309 310 311
{
    BIGNUM *t;

    if (a == NULL)
        return NULL;
    bn_check_top(a);

R
Rich Salz 已提交
312
    t = BN_get_flags(a, BN_FLG_SECURE) ? BN_secure_new() : BN_new();
313 314 315 316 317 318 319 320 321
    if (t == NULL)
        return NULL;
    if (!BN_copy(t, a)) {
        BN_free(t);
        return NULL;
    }
    bn_check_top(t);
    return t;
}
322

323
BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
324 325
{
    bn_check_top(b);
326

327
    if (a == b)
328
        return a;
329
    if (bn_wexpand(a, b->top) == NULL)
330
        return NULL;
331

332 333
    if (b->top > 0)
        memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
334

335
    a->neg = b->neg;
336 337
    a->top = b->top;
    a->flags |= b->flags & BN_FLG_FIXED_TOP;
338
    bn_check_top(a);
339
    return a;
340
}
341

B
Billy Brumley 已提交
342 343
#define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \
                                    | BN_FLG_CONSTTIME   \
344 345
                                    | BN_FLG_SECURE      \
                                    | BN_FLG_FIXED_TOP))
B
Billy Brumley 已提交
346 347
#define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED))

B
Bodo Möller 已提交
348
void BN_swap(BIGNUM *a, BIGNUM *b)
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
{
    int flags_old_a, flags_old_b;
    BN_ULONG *tmp_d;
    int tmp_top, tmp_dmax, tmp_neg;

    bn_check_top(a);
    bn_check_top(b);

    flags_old_a = a->flags;
    flags_old_b = b->flags;

    tmp_d = a->d;
    tmp_top = a->top;
    tmp_dmax = a->dmax;
    tmp_neg = a->neg;

    a->d = b->d;
    a->top = b->top;
    a->dmax = b->dmax;
    a->neg = b->neg;

    b->d = tmp_d;
    b->top = tmp_top;
    b->dmax = tmp_dmax;
    b->neg = tmp_neg;

B
Billy Brumley 已提交
375 376
    a->flags = FLAGS_STRUCT(flags_old_a) | FLAGS_DATA(flags_old_b);
    b->flags = FLAGS_STRUCT(flags_old_b) | FLAGS_DATA(flags_old_a);
377 378 379
    bn_check_top(a);
    bn_check_top(b);
}
B
Bodo Möller 已提交
380

U
Ulf Möller 已提交
381
void BN_clear(BIGNUM *a)
382
{
383 384
    if (a == NULL)
        return;
385 386
    bn_check_top(a);
    if (a->d != NULL)
387
        OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax);
388
    a->neg = 0;
389 390
    a->top = 0;
    a->flags &= ~BN_FLG_FIXED_TOP;
391
}
392

393
BN_ULONG BN_get_word(const BIGNUM *a)
394 395 396 397 398 399 400 401
{
    if (a->top > 1)
        return BN_MASK2;
    else if (a->top == 1)
        return a->d[0];
    /* a->top == 0 */
    return 0;
}
402

403
int BN_set_word(BIGNUM *a, BN_ULONG w)
404 405 406
{
    bn_check_top(a);
    if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
K
KaoruToda 已提交
407
        return 0;
408 409 410
    a->neg = 0;
    a->d[0] = w;
    a->top = (w ? 1 : 0);
411
    a->flags &= ~BN_FLG_FIXED_TOP;
412
    bn_check_top(a);
413
    return 1;
414
}
415

416
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
417 418 419 420 421 422 423 424 425
{
    unsigned int i, m;
    unsigned int n;
    BN_ULONG l;
    BIGNUM *bn = NULL;

    if (ret == NULL)
        ret = bn = BN_new();
    if (ret == NULL)
K
KaoruToda 已提交
426
        return NULL;
427
    bn_check_top(ret);
R
Rich Salz 已提交
428
    /* Skip leading zero's. */
R
Rich Salz 已提交
429
    for ( ; len > 0 && *s == 0; s++, len--)
R
Rich Salz 已提交
430
        continue;
431 432 433
    n = len;
    if (n == 0) {
        ret->top = 0;
K
KaoruToda 已提交
434
        return ret;
435 436 437 438
    }
    i = ((n - 1) / BN_BYTES) + 1;
    m = ((n - 1) % (BN_BYTES));
    if (bn_wexpand(ret, (int)i) == NULL) {
R
Rich Salz 已提交
439
        BN_free(bn);
440 441 442 443
        return NULL;
    }
    ret->top = i;
    ret->neg = 0;
R
Rich Salz 已提交
444
    l = 0;
445 446 447 448 449 450 451 452 453 454 455 456 457
    while (n--) {
        l = (l << 8L) | *(s++);
        if (m-- == 0) {
            ret->d[--i] = l;
            l = 0;
            m = BN_BYTES - 1;
        }
    }
    /*
     * need to call this due to clear byte at top if avoiding having the top
     * bit set (-ve number)
     */
    bn_correct_top(ret);
K
KaoruToda 已提交
458
    return ret;
459
}
460

461 462
typedef enum {big, little} endianess_t;

463
/* ignore negative */
464 465
static
int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianess_t endianess)
466
{
467
    int n;
468
    size_t i, lasti, j, atop, mask;
469 470
    BN_ULONG l;

471 472 473 474 475
    /*
     * In case |a| is fixed-top, BN_num_bytes can return bogus length,
     * but it's assumed that fixed-top inputs ought to be "nominated"
     * even for padded output, so it works out...
     */
476
    n = BN_num_bytes(a);
477
    if (tolen == -1) {
478
        tolen = n;
479 480
    } else if (tolen < n) {     /* uncommon/unlike case */
        BIGNUM temp = *a;
481

482 483 484 485 486 487 488 489 490
        bn_correct_top(&temp);
        n = BN_num_bytes(&temp);
        if (tolen < n)
            return -1;
    }

    /* Swipe through whole available data and don't give away padded zero. */
    atop = a->dmax * BN_BYTES;
    if (atop == 0) {
491 492
        OPENSSL_cleanse(to, tolen);
        return tolen;
D
Dr. Stephen Henson 已提交
493
    }
494

495 496
    lasti = atop - 1;
    atop = a->top * BN_BYTES;
497 498 499 500
    if (endianess == big)
        to += tolen; /* start from the end of the buffer */
    for (i = 0, j = 0; j < (size_t)tolen; j++) {
        unsigned char val;
501
        l = a->d[i / BN_BYTES];
502
        mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
503 504 505 506 507
        val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
        if (endianess == big)
            *--to = val;
        else
            *to++ = val;
508
        i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
509
    }
510

D
Dr. Stephen Henson 已提交
511 512 513 514 515 516 517
    return tolen;
}

int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
{
    if (tolen < 0)
        return -1;
518
    return bn2binpad(a, to, tolen, big);
D
Dr. Stephen Henson 已提交
519 520 521 522
}

int BN_bn2bin(const BIGNUM *a, unsigned char *to)
{
523
    return bn2binpad(a, to, -1, big);
D
Dr. Stephen Henson 已提交
524 525 526 527 528 529 530 531 532 533 534 535
}

BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
{
    unsigned int i, m;
    unsigned int n;
    BN_ULONG l;
    BIGNUM *bn = NULL;

    if (ret == NULL)
        ret = bn = BN_new();
    if (ret == NULL)
K
KaoruToda 已提交
536
        return NULL;
D
Dr. Stephen Henson 已提交
537
    bn_check_top(ret);
K
Kurt Roeckx 已提交
538
    s += len;
D
Dr. Stephen Henson 已提交
539
    /* Skip trailing zeroes. */
K
Kurt Roeckx 已提交
540
    for ( ; len > 0 && s[-1] == 0; s--, len--)
D
Dr. Stephen Henson 已提交
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
        continue;
    n = len;
    if (n == 0) {
        ret->top = 0;
        return ret;
    }
    i = ((n - 1) / BN_BYTES) + 1;
    m = ((n - 1) % (BN_BYTES));
    if (bn_wexpand(ret, (int)i) == NULL) {
        BN_free(bn);
        return NULL;
    }
    ret->top = i;
    ret->neg = 0;
    l = 0;
    while (n--) {
K
Kurt Roeckx 已提交
557 558
        s--;
        l = (l << 8L) | *s;
D
Dr. Stephen Henson 已提交
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
        if (m-- == 0) {
            ret->d[--i] = l;
            l = 0;
            m = BN_BYTES - 1;
        }
    }
    /*
     * need to call this due to clear byte at top if avoiding having the top
     * bit set (-ve number)
     */
    bn_correct_top(ret);
    return ret;
}

int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
{
575
    if (tolen < 0)
D
Dr. Stephen Henson 已提交
576
        return -1;
577
    return bn2binpad(a, to, tolen, little);
578
}
579

580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret)
{
#ifdef B_ENDIAN
    return BN_bin2bn(s, len, ret);
#else
    return BN_lebin2bn(s, len, ret);
#endif
}

int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen)
{
#ifdef B_ENDIAN
    return BN_bn2binpad(a, to, tolen);
#else
    return BN_bn2lebinpad(a, to, tolen);
#endif
}

598
int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
599 600 601 602 603 604 605 606 607
{
    int i;
    BN_ULONG t1, t2, *ap, *bp;

    bn_check_top(a);
    bn_check_top(b);

    i = a->top - b->top;
    if (i != 0)
K
KaoruToda 已提交
608
        return i;
609 610 611 612 613 614 615 616
    ap = a->d;
    bp = b->d;
    for (i = a->top - 1; i >= 0; i--) {
        t1 = ap[i];
        t2 = bp[i];
        if (t1 != t2)
            return ((t1 > t2) ? 1 : -1);
    }
K
KaoruToda 已提交
617
    return 0;
618
}
619

620
int BN_cmp(const BIGNUM *a, const BIGNUM *b)
621 622 623 624 625 626 627
{
    int i;
    int gt, lt;
    BN_ULONG t1, t2;

    if ((a == NULL) || (b == NULL)) {
        if (a != NULL)
K
KaoruToda 已提交
628
            return -1;
629
        else if (b != NULL)
630
            return 1;
631
        else
K
KaoruToda 已提交
632
            return 0;
633 634 635 636 637 638 639
    }

    bn_check_top(a);
    bn_check_top(b);

    if (a->neg != b->neg) {
        if (a->neg)
K
KaoruToda 已提交
640
            return -1;
641
        else
642
            return 1;
643 644 645 646 647 648 649 650 651 652
    }
    if (a->neg == 0) {
        gt = 1;
        lt = -1;
    } else {
        gt = -1;
        lt = 1;
    }

    if (a->top > b->top)
K
KaoruToda 已提交
653
        return gt;
654
    if (a->top < b->top)
K
KaoruToda 已提交
655
        return lt;
656 657 658 659
    for (i = a->top - 1; i >= 0; i--) {
        t1 = a->d[i];
        t2 = b->d[i];
        if (t1 > t2)
K
KaoruToda 已提交
660
            return gt;
661
        if (t1 < t2)
K
KaoruToda 已提交
662
            return lt;
663
    }
K
KaoruToda 已提交
664
    return 0;
665
}
666

U
Ulf Möller 已提交
667
int BN_set_bit(BIGNUM *a, int n)
668 669 670 671 672 673 674 675 676 677
{
    int i, j, k;

    if (n < 0)
        return 0;

    i = n / BN_BITS2;
    j = n % BN_BITS2;
    if (a->top <= i) {
        if (bn_wexpand(a, i + 1) == NULL)
K
KaoruToda 已提交
678
            return 0;
679 680 681
        for (k = a->top; k < i + 1; k++)
            a->d[k] = 0;
        a->top = i + 1;
682
        a->flags &= ~BN_FLG_FIXED_TOP;
683 684 685 686
    }

    a->d[i] |= (((BN_ULONG)1) << j);
    bn_check_top(a);
687
    return 1;
688
}
689

U
Ulf Möller 已提交
690
int BN_clear_bit(BIGNUM *a, int n)
691 692
{
    int i, j;
693

694 695 696
    bn_check_top(a);
    if (n < 0)
        return 0;
697

698 699 700
    i = n / BN_BITS2;
    j = n % BN_BITS2;
    if (a->top <= i)
K
KaoruToda 已提交
701
        return 0;
702

703 704
    a->d[i] &= (~(((BN_ULONG)1) << j));
    bn_correct_top(a);
705
    return 1;
706
}
707

708
int BN_is_bit_set(const BIGNUM *a, int n)
709 710 711 712 713 714 715 716 717 718 719 720
{
    int i, j;

    bn_check_top(a);
    if (n < 0)
        return 0;
    i = n / BN_BITS2;
    j = n % BN_BITS2;
    if (a->top <= i)
        return 0;
    return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
}
721

U
Ulf Möller 已提交
722
int BN_mask_bits(BIGNUM *a, int n)
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
{
    int b, w;

    bn_check_top(a);
    if (n < 0)
        return 0;

    w = n / BN_BITS2;
    b = n % BN_BITS2;
    if (w >= a->top)
        return 0;
    if (b == 0)
        a->top = w;
    else {
        a->top = w + 1;
        a->d[w] &= ~(BN_MASK2 << b);
    }
    bn_correct_top(a);
741
    return 1;
742
}
743

744
void BN_set_negative(BIGNUM *a, int b)
745 746 747 748 749 750
{
    if (b && !BN_is_zero(a))
        a->neg = 1;
    else
        a->neg = 0;
}
751

752
int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
753 754 755 756
{
    int i;
    BN_ULONG aa, bb;

757 758 759
    if (n == 0)
        return 0;

760 761 762 763 764 765 766 767 768 769
    aa = a[n - 1];
    bb = b[n - 1];
    if (aa != bb)
        return ((aa > bb) ? 1 : -1);
    for (i = n - 2; i >= 0; i--) {
        aa = a[i];
        bb = b[i];
        if (aa != bb)
            return ((aa > bb) ? 1 : -1);
    }
K
KaoruToda 已提交
770
    return 0;
771 772 773 774
}

/*
 * Here follows a specialised variants of bn_cmp_words().  It has the
D
Dmitry-Me 已提交
775
 * capability of performing the operation on arrays of different sizes. The
776
 * sizes of those arrays is expressed through cl, which is the common length
D
Dmitry-Me 已提交
777
 * ( basically, min(len(a),len(b)) ), and dl, which is the delta between the
778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
 * two lengths, calculated as len(a)-len(b). All lengths are the number of
 * BN_ULONGs...
 */

int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
{
    int n, i;
    n = cl - 1;

    if (dl < 0) {
        for (i = dl; i < 0; i++) {
            if (b[n - i] != 0)
                return -1;      /* a < b */
        }
    }
    if (dl > 0) {
        for (i = dl; i > 0; i--) {
            if (a[n + i] != 0)
                return 1;       /* a > b */
        }
    }
    return bn_cmp_words(a, b, cl);
}

B
Billy Brumley 已提交
802
/*-
803
 * Constant-time conditional swap of a and b.
B
Billy Brumley 已提交
804 805 806 807
 * a and b are swapped if condition is not 0.
 * nwords is the number of words to swap.
 * Assumes that at least nwords are allocated in both a and b.
 * Assumes that no more than nwords are used by either a or b.
D
Dr. Stephen Henson 已提交
808 809
 */
void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
810 811 812
{
    BN_ULONG t;
    int i;
D
Dr. Stephen Henson 已提交
813

B
Billy Brumley 已提交
814 815 816
    if (a == b)
        return;

817 818
    bn_wcheck_size(a, nwords);
    bn_wcheck_size(b, nwords);
D
Dr. Stephen Henson 已提交
819

B
Billy Brumley 已提交
820
    condition = ((~condition & ((condition - 1))) >> (BN_BITS2 - 1)) - 1;
D
Dr. Stephen Henson 已提交
821

822 823 824
    t = (a->top ^ b->top) & condition;
    a->top ^= t;
    b->top ^= t;
D
Dr. Stephen Henson 已提交
825

826 827 828 829
    t = (a->neg ^ b->neg) & condition;
    a->neg ^= t;
    b->neg ^= t;

830
    /*-
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
     * BN_FLG_STATIC_DATA: indicates that data may not be written to. Intention
     * is actually to treat it as it's read-only data, and some (if not most)
     * of it does reside in read-only segment. In other words observation of
     * BN_FLG_STATIC_DATA in BN_consttime_swap should be treated as fatal
     * condition. It would either cause SEGV or effectively cause data
     * corruption.
     *
     * BN_FLG_MALLOCED: refers to BN structure itself, and hence must be
     * preserved.
     *
     * BN_FLG_SECURE: must be preserved, because it determines how x->d was
     * allocated and hence how to free it.
     *
     * BN_FLG_CONSTTIME: sufficient to mask and swap
     *
     * BN_FLG_FIXED_TOP: indicates that we haven't called bn_correct_top() on
     * the data, so the d array may be padded with additional 0 values (i.e.
     * top could be greater than the minimal value that it could be). We should
     * be swapping it
850
     */
851 852 853 854

#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP)

    t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition;
855 856 857
    a->flags ^= t;
    b->flags ^= t;

B
Billy Brumley 已提交
858 859 860 861 862 863
    /* conditionally swap the data */
    for (i = 0; i < nwords; i++) {
        t = (a->d[i] ^ b->d[i]) & condition;
        a->d[i] ^= t;
        b->d[i] ^= t;
    }
D
Dr. Stephen Henson 已提交
864
}
865

B
Billy Brumley 已提交
866 867
#undef BN_CONSTTIME_SWAP_FLAGS

868 869 870
/* Bits of security, see SP800-57 */

int BN_security_bits(int L, int N)
871 872 873 874
{
    int secbits, bits;
    if (L >= 15360)
        secbits = 256;
875
    else if (L >= 7680)
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891
        secbits = 192;
    else if (L >= 3072)
        secbits = 128;
    else if (L >= 2048)
        secbits = 112;
    else if (L >= 1024)
        secbits = 80;
    else
        return 0;
    if (N == -1)
        return secbits;
    bits = N / 2;
    if (bits < 80)
        return 0;
    return bits >= secbits ? secbits : bits;
}
892 893

void BN_zero_ex(BIGNUM *a)
894 895
{
    a->neg = 0;
896 897
    a->top = 0;
    a->flags &= ~BN_FLG_FIXED_TOP;
898
}
899 900

int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
901 902 903
{
    return ((a->top == 1) && (a->d[0] == w)) || ((w == 0) && (a->top == 0));
}
904 905

int BN_is_zero(const BIGNUM *a)
906 907 908
{
    return a->top == 0;
}
909 910

int BN_is_one(const BIGNUM *a)
911 912 913
{
    return BN_abs_is_word(a, 1) && !a->neg;
}
914 915

int BN_is_word(const BIGNUM *a, const BN_ULONG w)
916 917 918
{
    return BN_abs_is_word(a, w) && (!w || !a->neg);
}
919 920

int BN_is_odd(const BIGNUM *a)
921 922 923
{
    return (a->top > 0) && (a->d[0] & 1);
}
924 925

int BN_is_negative(const BIGNUM *a)
926 927 928
{
    return (a->neg != 0);
}
929

930 931 932 933 934
int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
                     BN_CTX *ctx)
{
    return BN_mod_mul_montgomery(r, a, &(mont->RR), mont, ctx);
}
935

936
void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
937 938 939 940 941 942 943
{
    dest->d = b->d;
    dest->top = b->top;
    dest->dmax = b->dmax;
    dest->neg = b->neg;
    dest->flags = ((dest->flags & BN_FLG_MALLOCED)
                   | (b->flags & ~BN_FLG_MALLOCED)
944
                   | BN_FLG_STATIC_DATA | flags);
945
}
946 947

BN_GENCB *BN_GENCB_new(void)
948 949
{
    BN_GENCB *ret;
950

R
Rich Salz 已提交
951
    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
952
        BNerr(BN_F_BN_GENCB_NEW, ERR_R_MALLOC_FAILURE);
K
KaoruToda 已提交
953
        return NULL;
954
    }
955

956 957
    return ret;
}
958 959

void BN_GENCB_free(BN_GENCB *cb)
960 961 962 963 964
{
    if (cb == NULL)
        return;
    OPENSSL_free(cb);
}
965 966

void BN_set_flags(BIGNUM *b, int n)
967 968 969
{
    b->flags |= n;
}
970 971

int BN_get_flags(const BIGNUM *b, int n)
972 973 974
{
    return b->flags & n;
}
975 976

/* Populate a BN_GENCB structure with an "old"-style callback */
977 978 979 980 981 982 983 984
void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback) (int, int, void *),
                      void *cb_arg)
{
    BN_GENCB *tmp_gencb = gencb;
    tmp_gencb->ver = 1;
    tmp_gencb->arg = cb_arg;
    tmp_gencb->cb.cb_1 = callback;
}
985 986

/* Populate a BN_GENCB structure with a "new"-style callback */
987 988 989 990 991 992 993 994
void BN_GENCB_set(BN_GENCB *gencb, int (*callback) (int, int, BN_GENCB *),
                  void *cb_arg)
{
    BN_GENCB *tmp_gencb = gencb;
    tmp_gencb->ver = 2;
    tmp_gencb->arg = cb_arg;
    tmp_gencb->cb.cb_2 = callback;
}
995 996

void *BN_GENCB_get_arg(BN_GENCB *cb)
997 998 999
{
    return cb->arg;
}
1000 1001

BIGNUM *bn_wexpand(BIGNUM *a, int words)
1002 1003 1004
{
    return (words <= a->dmax) ? a : bn_expand2(a, words);
}
1005 1006

void bn_correct_top(BIGNUM *a)
1007 1008 1009 1010 1011
{
    BN_ULONG *ftl;
    int tmp_top = a->top;

    if (tmp_top > 0) {
K
Kurt Roeckx 已提交
1012 1013 1014
        for (ftl = &(a->d[tmp_top]); tmp_top > 0; tmp_top--) {
            ftl--;
            if (*ftl != 0)
1015
                break;
K
Kurt Roeckx 已提交
1016
        }
1017 1018
        a->top = tmp_top;
    }
R
Rich Salz 已提交
1019 1020
    if (a->top == 0)
        a->neg = 0;
1021
    a->flags &= ~BN_FLG_FIXED_TOP;
1022 1023
    bn_pollute(a);
}