bn_lib.c 22.6 KB
Newer Older
R
Rich Salz 已提交
1
/*
M
Matt Caswell 已提交
2
 * Copyright 1995-2020 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
#ifndef OPENSSL_NO_DEPRECATED_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 326
    int bn_words;

327
    bn_check_top(b);
328

329 330
    bn_words = BN_get_flags(b, BN_FLG_CONSTTIME) ? b->dmax : b->top;

331
    if (a == b)
332
        return a;
333
    if (bn_wexpand(a, bn_words) == NULL)
334
        return NULL;
335

336
    if (b->top > 0)
337
        memcpy(a->d, b->d, sizeof(b->d[0]) * bn_words);
338

339
    a->neg = b->neg;
340 341
    a->top = b->top;
    a->flags |= b->flags & BN_FLG_FIXED_TOP;
342
    bn_check_top(a);
343
    return a;
344
}
345

B
Billy Brumley 已提交
346 347
#define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \
                                    | BN_FLG_CONSTTIME   \
348 349
                                    | BN_FLG_SECURE      \
                                    | BN_FLG_FIXED_TOP))
B
Billy Brumley 已提交
350 351
#define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED))

B
Bodo Möller 已提交
352
void BN_swap(BIGNUM *a, BIGNUM *b)
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
{
    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 已提交
379 380
    a->flags = FLAGS_STRUCT(flags_old_a) | FLAGS_DATA(flags_old_b);
    b->flags = FLAGS_STRUCT(flags_old_b) | FLAGS_DATA(flags_old_a);
381 382 383
    bn_check_top(a);
    bn_check_top(b);
}
B
Bodo Möller 已提交
384

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

397
BN_ULONG BN_get_word(const BIGNUM *a)
398 399 400 401 402 403 404 405
{
    if (a->top > 1)
        return BN_MASK2;
    else if (a->top == 1)
        return a->d[0];
    /* a->top == 0 */
    return 0;
}
406

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

420
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
421 422 423 424 425 426 427 428 429
{
    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 已提交
430
        return NULL;
431
    bn_check_top(ret);
R
Rich Salz 已提交
432
    /* Skip leading zero's. */
R
Rich Salz 已提交
433
    for ( ; len > 0 && *s == 0; s++, len--)
R
Rich Salz 已提交
434
        continue;
435 436 437
    n = len;
    if (n == 0) {
        ret->top = 0;
K
KaoruToda 已提交
438
        return ret;
439 440 441 442
    }
    i = ((n - 1) / BN_BYTES) + 1;
    m = ((n - 1) % (BN_BYTES));
    if (bn_wexpand(ret, (int)i) == NULL) {
R
Rich Salz 已提交
443
        BN_free(bn);
444 445 446 447
        return NULL;
    }
    ret->top = i;
    ret->neg = 0;
R
Rich Salz 已提交
448
    l = 0;
449 450 451 452 453 454 455 456 457 458 459 460 461
    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 已提交
462
    return ret;
463
}
464

465 466
typedef enum {big, little} endianess_t;

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

475 476 477 478 479
    /*
     * 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...
     */
480
    n = BN_num_bytes(a);
481
    if (tolen == -1) {
482
        tolen = n;
483 484
    } else if (tolen < n) {     /* uncommon/unlike case */
        BIGNUM temp = *a;
485

486 487 488 489 490 491 492 493 494
        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) {
495 496
        OPENSSL_cleanse(to, tolen);
        return tolen;
D
Dr. Stephen Henson 已提交
497
    }
498

499 500
    lasti = atop - 1;
    atop = a->top * BN_BYTES;
501 502 503 504
    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;
505
        l = a->d[i / BN_BYTES];
506
        mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
507 508 509 510 511
        val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
        if (endianess == big)
            *--to = val;
        else
            *to++ = val;
512
        i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
513
    }
514

D
Dr. Stephen Henson 已提交
515 516 517 518 519 520 521
    return tolen;
}

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

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

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 已提交
540
        return NULL;
D
Dr. Stephen Henson 已提交
541
    bn_check_top(ret);
K
Kurt Roeckx 已提交
542
    s += len;
D
Dr. Stephen Henson 已提交
543
    /* Skip trailing zeroes. */
K
Kurt Roeckx 已提交
544
    for ( ; len > 0 && s[-1] == 0; s--, len--)
D
Dr. Stephen Henson 已提交
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
        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 已提交
561 562
        s--;
        l = (l << 8L) | *s;
D
Dr. Stephen Henson 已提交
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
        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)
{
579
    if (tolen < 0)
D
Dr. Stephen Henson 已提交
580
        return -1;
581
    return bn2binpad(a, to, tolen, little);
582
}
583

584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
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
}

602
int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
603 604 605 606 607 608 609 610 611
{
    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 已提交
612
        return i;
613 614 615 616 617 618 619 620
    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 已提交
621
    return 0;
622
}
623

624
int BN_cmp(const BIGNUM *a, const BIGNUM *b)
625 626 627 628 629 630 631
{
    int i;
    int gt, lt;
    BN_ULONG t1, t2;

    if ((a == NULL) || (b == NULL)) {
        if (a != NULL)
K
KaoruToda 已提交
632
            return -1;
633
        else if (b != NULL)
634
            return 1;
635
        else
K
KaoruToda 已提交
636
            return 0;
637 638 639 640 641 642 643
    }

    bn_check_top(a);
    bn_check_top(b);

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

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

U
Ulf Möller 已提交
671
int BN_set_bit(BIGNUM *a, int n)
672 673 674 675 676 677 678 679 680 681
{
    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 已提交
682
            return 0;
683 684 685
        for (k = a->top; k < i + 1; k++)
            a->d[k] = 0;
        a->top = i + 1;
686
        a->flags &= ~BN_FLG_FIXED_TOP;
687 688 689 690
    }

    a->d[i] |= (((BN_ULONG)1) << j);
    bn_check_top(a);
691
    return 1;
692
}
693

U
Ulf Möller 已提交
694
int BN_clear_bit(BIGNUM *a, int n)
695 696
{
    int i, j;
697

698 699 700
    bn_check_top(a);
    if (n < 0)
        return 0;
701

702 703 704
    i = n / BN_BITS2;
    j = n % BN_BITS2;
    if (a->top <= i)
K
KaoruToda 已提交
705
        return 0;
706

707 708
    a->d[i] &= (~(((BN_ULONG)1) << j));
    bn_correct_top(a);
709
    return 1;
710
}
711

712
int BN_is_bit_set(const BIGNUM *a, int n)
713 714 715 716 717 718 719 720 721 722 723 724
{
    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));
}
725

U
Ulf Möller 已提交
726
int BN_mask_bits(BIGNUM *a, int n)
727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744
{
    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);
745
    return 1;
746
}
747

748
void BN_set_negative(BIGNUM *a, int b)
749 750 751 752 753 754
{
    if (b && !BN_is_zero(a))
        a->neg = 1;
    else
        a->neg = 0;
}
755

756
int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
757 758 759 760
{
    int i;
    BN_ULONG aa, bb;

761 762 763
    if (n == 0)
        return 0;

764 765 766 767 768 769 770 771 772 773
    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 已提交
774
    return 0;
775 776 777 778
}

/*
 * Here follows a specialised variants of bn_cmp_words().  It has the
D
Dmitry-Me 已提交
779
 * capability of performing the operation on arrays of different sizes. The
780
 * sizes of those arrays is expressed through cl, which is the common length
D
Dmitry-Me 已提交
781
 * ( basically, min(len(a),len(b)) ), and dl, which is the delta between the
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
 * 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 已提交
806
/*-
807
 * Constant-time conditional swap of a and b.
B
Billy Brumley 已提交
808 809 810 811
 * 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 已提交
812 813
 */
void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
814 815 816
{
    BN_ULONG t;
    int i;
D
Dr. Stephen Henson 已提交
817

B
Billy Brumley 已提交
818 819 820
    if (a == b)
        return;

821 822
    bn_wcheck_size(a, nwords);
    bn_wcheck_size(b, nwords);
D
Dr. Stephen Henson 已提交
823

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

826 827 828
    t = (a->top ^ b->top) & condition;
    a->top ^= t;
    b->top ^= t;
D
Dr. Stephen Henson 已提交
829

830 831 832 833
    t = (a->neg ^ b->neg) & condition;
    a->neg ^= t;
    b->neg ^= t;

834
    /*-
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853
     * 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
854
     */
855 856 857 858

#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP)

    t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition;
859 860 861
    a->flags ^= t;
    b->flags ^= t;

B
Billy Brumley 已提交
862 863 864 865 866 867
    /* 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 已提交
868
}
869

B
Billy Brumley 已提交
870 871
#undef BN_CONSTTIME_SWAP_FLAGS

872 873 874
/* Bits of security, see SP800-57 */

int BN_security_bits(int L, int N)
875 876 877 878
{
    int secbits, bits;
    if (L >= 15360)
        secbits = 256;
879
    else if (L >= 7680)
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895
        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;
}
896 897

void BN_zero_ex(BIGNUM *a)
898 899
{
    a->neg = 0;
900 901
    a->top = 0;
    a->flags &= ~BN_FLG_FIXED_TOP;
902
}
903 904

int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
905 906 907
{
    return ((a->top == 1) && (a->d[0] == w)) || ((w == 0) && (a->top == 0));
}
908 909

int BN_is_zero(const BIGNUM *a)
910 911 912
{
    return a->top == 0;
}
913 914

int BN_is_one(const BIGNUM *a)
915 916 917
{
    return BN_abs_is_word(a, 1) && !a->neg;
}
918 919

int BN_is_word(const BIGNUM *a, const BN_ULONG w)
920 921 922
{
    return BN_abs_is_word(a, w) && (!w || !a->neg);
}
923 924

int BN_is_odd(const BIGNUM *a)
925 926 927
{
    return (a->top > 0) && (a->d[0] & 1);
}
928 929

int BN_is_negative(const BIGNUM *a)
930 931 932
{
    return (a->neg != 0);
}
933

934 935 936 937 938
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);
}
939

940
void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
941 942 943 944 945 946 947
{
    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)
948
                   | BN_FLG_STATIC_DATA | flags);
949
}
950 951

BN_GENCB *BN_GENCB_new(void)
952 953
{
    BN_GENCB *ret;
954

R
Rich Salz 已提交
955
    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
956
        BNerr(BN_F_BN_GENCB_NEW, ERR_R_MALLOC_FAILURE);
K
KaoruToda 已提交
957
        return NULL;
958
    }
959

960 961
    return ret;
}
962 963

void BN_GENCB_free(BN_GENCB *cb)
964 965 966 967 968
{
    if (cb == NULL)
        return;
    OPENSSL_free(cb);
}
969 970

void BN_set_flags(BIGNUM *b, int n)
971 972 973
{
    b->flags |= n;
}
974 975

int BN_get_flags(const BIGNUM *b, int n)
976 977 978
{
    return b->flags & n;
}
979 980

/* Populate a BN_GENCB structure with an "old"-style callback */
981 982 983 984 985 986 987 988
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;
}
989 990

/* Populate a BN_GENCB structure with a "new"-style callback */
991 992 993 994 995 996 997 998
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;
}
999 1000

void *BN_GENCB_get_arg(BN_GENCB *cb)
1001 1002 1003
{
    return cb->arg;
}
1004 1005

BIGNUM *bn_wexpand(BIGNUM *a, int words)
1006 1007 1008
{
    return (words <= a->dmax) ? a : bn_expand2(a, words);
}
1009 1010

void bn_correct_top(BIGNUM *a)
1011 1012 1013 1014 1015
{
    BN_ULONG *ftl;
    int tmp_top = a->top;

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