bn_lib.c 22.7 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 "internal/endian.h"
14
#include "bn_local.h"
15
#include <openssl/opensslconf.h>
16
#include "internal/constant_time.h"
17

18
/* This stuff appears to be completely unused, so is deprecated */
19
#ifndef OPENSSL_NO_DEPRECATED_0_9_8
20 21
/*-
 * For a 32 bit machine
22 23 24 25 26 27 28 29
 * 2 -   4 ==  128
 * 3 -   8 ==  256
 * 4 -  16 ==  512
 * 5 -  32 == 1024
 * 6 -  64 == 2048
 * 7 - 128 == 4096
 * 8 - 256 == 8192
 */
30 31 32 33 34 35 36 37
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) */
38

U
Ulf Möller 已提交
39
void BN_set_params(int mult, int high, int low, int mont)
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 65
{
    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;
    }
}
66

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

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

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

U
Ulf Möller 已提交
91
int BN_num_bits_word(BN_ULONG l)
92
{
93 94 95 96 97 98 99 100 101
    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;
102
#endif
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 133

    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;
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 165
/*
 * 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;
}

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

171 172 173 174 175 176 177 178 179 180 181 182 183
    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);
    }

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

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

P
Pauli 已提交
190
static void bn_free_d(BIGNUM *a, int clear)
R
Rich Salz 已提交
191
{
F
FdaSilvaYY 已提交
192
    if (BN_get_flags(a, BN_FLG_SECURE))
P
Pauli 已提交
193 194 195
        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 已提交
196 197 198 199 200
    else
        OPENSSL_free(a->d);
}


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

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

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

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

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

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

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

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

    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 已提交
264
        return NULL;
265
    }
F
FdaSilvaYY 已提交
266
    if (BN_get_flags(b, BN_FLG_SECURE))
267
        a = OPENSSL_secure_zalloc(words * sizeof(*a));
R
Rich Salz 已提交
268
    else
269 270
        a = OPENSSL_zalloc(words * sizeof(*a));
    if (a == NULL) {
271
        BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
K
KaoruToda 已提交
272
        return NULL;
273
    }
274

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

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

/*
 * 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.
 */
289

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

302 303
    return b;
}
304

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

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

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

324
BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
325
{
326 327
    int bn_words;

328
    bn_check_top(b);
329

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

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

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

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

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

B
Bodo Möller 已提交
353
void BN_swap(BIGNUM *a, BIGNUM *b)
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 379
{
    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 已提交
380 381
    a->flags = FLAGS_STRUCT(flags_old_a) | FLAGS_DATA(flags_old_b);
    b->flags = FLAGS_STRUCT(flags_old_b) | FLAGS_DATA(flags_old_a);
382 383 384
    bn_check_top(a);
    bn_check_top(b);
}
B
Bodo Möller 已提交
385

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

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

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

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

466 467
typedef enum {big, little} endianess_t;

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

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

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

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

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

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

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

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

585 586
BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret)
{
587 588 589 590
    DECLARE_IS_ENDIAN;

    if (IS_LITTLE_ENDIAN)
        return BN_lebin2bn(s, len, ret);
591 592 593 594 595
    return BN_bin2bn(s, len, ret);
}

int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen)
{
596 597 598 599
    DECLARE_IS_ENDIAN;

    if (IS_LITTLE_ENDIAN)
        return BN_bn2lebinpad(a, to, tolen);
600 601 602
    return BN_bn2binpad(a, to, tolen);
}

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

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

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

    bn_check_top(a);
    bn_check_top(b);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP)

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

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

B
Billy Brumley 已提交
871 872
#undef BN_CONSTTIME_SWAP_FLAGS

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

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

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

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

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

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

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

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

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

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

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

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

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

961 962
    return ret;
}
963 964

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

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

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

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

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

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

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

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

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