bn_lib.c 21.4 KB
Newer Older
R
Rich Salz 已提交
1 2
/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * 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_lcl.h"
14
#include <openssl/opensslconf.h>
15

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

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

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

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

86 87
    return (&const_one);
}
88

U
Ulf Möller 已提交
89
int BN_num_bits_word(BN_ULONG l)
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
{
    static const unsigned char bits[256] = {
        0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
    };
109

110
#if defined(SIXTY_FOUR_BIT_LONG)
111 112 113 114 115 116 117 118 119 120 121 122 123
    if (l & 0xffffffff00000000L) {
        if (l & 0xffff000000000000L) {
            if (l & 0xff00000000000000L) {
                return (bits[(int)(l >> 56)] + 56);
            } else
                return (bits[(int)(l >> 48)] + 48);
        } else {
            if (l & 0x0000ff0000000000L) {
                return (bits[(int)(l >> 40)] + 40);
            } else
                return (bits[(int)(l >> 32)] + 32);
        }
    } else
124
#else
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
# ifdef SIXTY_FOUR_BIT
    if (l & 0xffffffff00000000LL) {
        if (l & 0xffff000000000000LL) {
            if (l & 0xff00000000000000LL) {
                return (bits[(int)(l >> 56)] + 56);
            } else
                return (bits[(int)(l >> 48)] + 48);
        } else {
            if (l & 0x0000ff0000000000LL) {
                return (bits[(int)(l >> 40)] + 40);
            } else
                return (bits[(int)(l >> 32)] + 32);
        }
    } else
# endif
140
#endif
141
    {
142
#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
143 144 145 146 147 148
        if (l & 0xffff0000L) {
            if (l & 0xff000000L)
                return (bits[(int)(l >> 24L)] + 24);
            else
                return (bits[(int)(l >> 16L)] + 16);
        } else
149
#endif
150
        {
151
#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
152 153 154
            if (l & 0xff00L)
                return (bits[(int)(l >> 8)] + 8);
            else
155
#endif
156 157 158 159
                return (bits[(int)(l)]);
        }
    }
}
160

161
int BN_num_bits(const BIGNUM *a)
162 163 164
{
    int i = a->top - 1;
    bn_check_top(a);
165

166 167 168 169
    if (BN_is_zero(a))
        return 0;
    return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
}
170

R
Rich Salz 已提交
171 172
static void bn_free_d(BIGNUM *a)
{
F
FdaSilvaYY 已提交
173
    if (BN_get_flags(a, BN_FLG_SECURE))
R
Rich Salz 已提交
174 175 176 177 178 179
        OPENSSL_secure_free(a->d);
    else
        OPENSSL_free(a->d);
}


U
Ulf Möller 已提交
180
void BN_clear_free(BIGNUM *a)
181 182 183 184 185 186 187 188
{
    int i;

    if (a == NULL)
        return;
    bn_check_top(a);
    if (a->d != NULL) {
        OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
R
Rich Salz 已提交
189 190
        if (!BN_get_flags(a, BN_FLG_STATIC_DATA))
            bn_free_d(a);
191 192
    }
    i = BN_get_flags(a, BN_FLG_MALLOCED);
R
Rich Salz 已提交
193
    OPENSSL_cleanse(a, sizeof(*a));
194 195 196
    if (i)
        OPENSSL_free(a);
}
197

U
Ulf Möller 已提交
198
void BN_free(BIGNUM *a)
199 200 201 202
{
    if (a == NULL)
        return;
    bn_check_top(a);
R
Rich Salz 已提交
203
    if (!BN_get_flags(a, BN_FLG_STATIC_DATA))
R
Rich Salz 已提交
204
        bn_free_d(a);
205 206 207
    if (a->flags & BN_FLG_MALLOCED)
        OPENSSL_free(a);
    else {
208
#if OPENSSL_API_COMPAT < 0x00908000L
209
        a->flags |= BN_FLG_FREE;
210
#endif
211 212 213
        a->d = NULL;
    }
}
214

R
Rich Salz 已提交
215
void bn_init(BIGNUM *a)
216
{
R
Rich Salz 已提交
217 218 219
    static BIGNUM nilbn;

    *a = nilbn;
220 221
    bn_check_top(a);
}
222

U
Ulf Möller 已提交
223
BIGNUM *BN_new(void)
224 225 226
{
    BIGNUM *ret;

R
Rich Salz 已提交
227
    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
228 229 230 231 232 233 234
        BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE);
        return (NULL);
    }
    ret->flags = BN_FLG_MALLOCED;
    bn_check_top(ret);
    return (ret);
}
235

R
Rich Salz 已提交
236 237 238
 BIGNUM *BN_secure_new(void)
 {
     BIGNUM *ret = BN_new();
239
     if (ret != NULL)
R
Rich Salz 已提交
240 241 242 243
         ret->flags |= BN_FLG_SECURE;
     return (ret);
 }

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

    bn_check_top(b);

    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);
        return (NULL);
    }
F
FdaSilvaYY 已提交
260
    if (BN_get_flags(b, BN_FLG_SECURE))
261
        a = OPENSSL_secure_zalloc(words * sizeof(*a));
R
Rich Salz 已提交
262
    else
263 264
        a = OPENSSL_zalloc(words * sizeof(*a));
    if (a == NULL) {
265 266 267
        BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
        return (NULL);
    }
268

269
    assert(b->top <= words);
270 271
    if (b->top > 0)
        memcpy(a, b->d, sizeof(*a) * b->top);
272

273
    return a;
274 275 276 277 278 279 280 281 282
}

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

284
BIGNUM *bn_expand2(BIGNUM *b, int words)
285 286 287 288 289 290 291
{
    bn_check_top(b);

    if (words > b->dmax) {
        BN_ULONG *a = bn_expand_internal(b, words);
        if (!a)
            return NULL;
R
Rich Salz 已提交
292
        if (b->d) {
R
Rich Salz 已提交
293 294
            OPENSSL_cleanse(b->d, b->dmax * sizeof(b->d[0]));
            bn_free_d(b);
R
Rich Salz 已提交
295
        }
296 297 298
        b->d = a;
        b->dmax = words;
    }
G
Geoff Thorpe 已提交
299

300 301 302
    bn_check_top(b);
    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 336 337
    if (BN_get_flags(b, BN_FLG_CONSTTIME) != 0)
        BN_set_flags(a, BN_FLG_CONSTTIME);

338 339 340
    a->top = b->top;
    a->neg = b->neg;
    bn_check_top(a);
341
    return a;
342
}
343

B
Bodo Möller 已提交
344
void BN_swap(BIGNUM *a, BIGNUM *b)
345 346 347 348 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 375 376 377
{
    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;

    a->flags =
        (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
    b->flags =
        (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
    bn_check_top(a);
    bn_check_top(b);
}
B
Bodo Möller 已提交
378

U
Ulf Möller 已提交
379
void BN_clear(BIGNUM *a)
380 381 382
{
    bn_check_top(a);
    if (a->d != NULL)
383
        OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax);
384 385 386
    a->top = 0;
    a->neg = 0;
}
387

388
BN_ULONG BN_get_word(const BIGNUM *a)
389 390 391 392 393 394 395 396
{
    if (a->top > 1)
        return BN_MASK2;
    else if (a->top == 1)
        return a->d[0];
    /* a->top == 0 */
    return 0;
}
397

398
int BN_set_word(BIGNUM *a, BN_ULONG w)
399 400 401 402 403 404 405 406
{
    bn_check_top(a);
    if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
        return (0);
    a->neg = 0;
    a->d[0] = w;
    a->top = (w ? 1 : 0);
    bn_check_top(a);
407
    return 1;
408
}
409

410
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
411 412 413 414 415 416 417 418 419 420 421
{
    unsigned int i, m;
    unsigned int n;
    BN_ULONG l;
    BIGNUM *bn = NULL;

    if (ret == NULL)
        ret = bn = BN_new();
    if (ret == NULL)
        return (NULL);
    bn_check_top(ret);
R
Rich Salz 已提交
422
    /* Skip leading zero's. */
R
Rich Salz 已提交
423
    for ( ; len > 0 && *s == 0; s++, len--)
R
Rich Salz 已提交
424
        continue;
425 426 427 428 429 430 431 432
    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) {
R
Rich Salz 已提交
433
        BN_free(bn);
434 435 436 437
        return NULL;
    }
    ret->top = i;
    ret->neg = 0;
R
Rich Salz 已提交
438
    l = 0;
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
    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);
    return (ret);
}
454 455

/* ignore negative */
D
Dr. Stephen Henson 已提交
456
static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
457
{
D
Dr. Stephen Henson 已提交
458
    int i;
459 460 461
    BN_ULONG l;

    bn_check_top(a);
D
Dr. Stephen Henson 已提交
462 463 464 465 466 467 468 469 470 471
    i = BN_num_bytes(a);
    if (tolen == -1)
        tolen = i;
    else if (tolen < i)
        return -1;
    /* Add leading zeroes if necessary */
    if (tolen > i) {
        memset(to, 0, tolen - i);
        to += tolen - i;
    }
472 473 474 475
    while (i--) {
        l = a->d[i / BN_BYTES];
        *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
    }
D
Dr. Stephen Henson 已提交
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
    return tolen;
}

int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
{
    if (tolen < 0)
        return -1;
    return bn2binpad(a, to, tolen);
}

int BN_bn2bin(const BIGNUM *a, unsigned char *to)
{
    return bn2binpad(a, to, -1);
}

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)
        return (NULL);
    bn_check_top(ret);
K
Kurt Roeckx 已提交
503
    s += len;
D
Dr. Stephen Henson 已提交
504
    /* Skip trailing zeroes. */
K
Kurt Roeckx 已提交
505
    for ( ; len > 0 && s[-1] == 0; s--, len--)
D
Dr. Stephen Henson 已提交
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
        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 已提交
522 523
        s--;
        l = (l << 8L) | *s;
D
Dr. Stephen Henson 已提交
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
        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)
{
    int i;
    BN_ULONG l;
    bn_check_top(a);
    i = BN_num_bytes(a);
    if (tolen < i)
        return -1;
    /* Add trailing zeroes if necessary */
    if (tolen > i)
        memset(to + i, 0, tolen - i);
K
Kurt Roeckx 已提交
549
    to += i;
D
Dr. Stephen Henson 已提交
550 551
    while (i--) {
        l = a->d[i / BN_BYTES];
K
Kurt Roeckx 已提交
552 553
        to--;
        *to = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
D
Dr. Stephen Henson 已提交
554 555
    }
    return tolen;
556
}
557

558
int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
{
    int i;
    BN_ULONG t1, t2, *ap, *bp;

    bn_check_top(a);
    bn_check_top(b);

    i = a->top - b->top;
    if (i != 0)
        return (i);
    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);
    }
    return (0);
}
579

580
int BN_cmp(const BIGNUM *a, const BIGNUM *b)
581 582 583 584 585 586 587 588 589
{
    int i;
    int gt, lt;
    BN_ULONG t1, t2;

    if ((a == NULL) || (b == NULL)) {
        if (a != NULL)
            return (-1);
        else if (b != NULL)
590
            return 1;
591 592 593 594 595 596 597 598 599 600 601
        else
            return (0);
    }

    bn_check_top(a);
    bn_check_top(b);

    if (a->neg != b->neg) {
        if (a->neg)
            return (-1);
        else
602
            return 1;
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
    }
    if (a->neg == 0) {
        gt = 1;
        lt = -1;
    } else {
        gt = -1;
        lt = 1;
    }

    if (a->top > b->top)
        return (gt);
    if (a->top < b->top)
        return (lt);
    for (i = a->top - 1; i >= 0; i--) {
        t1 = a->d[i];
        t2 = b->d[i];
        if (t1 > t2)
            return (gt);
        if (t1 < t2)
            return (lt);
    }
    return (0);
}
626

U
Ulf Möller 已提交
627
int BN_set_bit(BIGNUM *a, int n)
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
{
    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)
            return (0);
        for (k = a->top; k < i + 1; k++)
            a->d[k] = 0;
        a->top = i + 1;
    }

    a->d[i] |= (((BN_ULONG)1) << j);
    bn_check_top(a);
646
    return 1;
647
}
648

U
Ulf Möller 已提交
649
int BN_clear_bit(BIGNUM *a, int n)
650 651
{
    int i, j;
652

653 654 655
    bn_check_top(a);
    if (n < 0)
        return 0;
656

657 658 659 660
    i = n / BN_BITS2;
    j = n % BN_BITS2;
    if (a->top <= i)
        return (0);
661

662 663
    a->d[i] &= (~(((BN_ULONG)1) << j));
    bn_correct_top(a);
664
    return 1;
665
}
666

667
int BN_is_bit_set(const BIGNUM *a, int n)
668 669 670 671 672 673 674 675 676 677 678 679
{
    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));
}
680

U
Ulf Möller 已提交
681
int BN_mask_bits(BIGNUM *a, int n)
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
{
    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);
700
    return 1;
701
}
702

703
void BN_set_negative(BIGNUM *a, int b)
704 705 706 707 708 709
{
    if (b && !BN_is_zero(a))
        a->neg = 1;
    else
        a->neg = 0;
}
710

711
int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
{
    int i;
    BN_ULONG aa, bb;

    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);
    }
    return (0);
}

/*
 * Here follows a specialised variants of bn_cmp_words().  It has the
D
Dmitry-Me 已提交
731
 * capability of performing the operation on arrays of different sizes. The
732
 * sizes of those arrays is expressed through cl, which is the common length
D
Dmitry-Me 已提交
733
 * ( basically, min(len(a),len(b)) ), and dl, which is the delta between the
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
 * 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);
}

/*
 * Constant-time conditional swap of a and b.
D
Dr. Stephen Henson 已提交
760 761 762 763 764 765
 * a and b are swapped if condition is not 0.  The code assumes that at most one bit of condition is set.
 * nwords is the number of words to swap.  The code assumes that at least nwords are allocated in both a and b,
 * and that no more than nwords are used by either a or b.
 * a and b cannot be the same number
 */
void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
766 767 768
{
    BN_ULONG t;
    int i;
D
Dr. Stephen Henson 已提交
769

770 771
    bn_wcheck_size(a, nwords);
    bn_wcheck_size(b, nwords);
D
Dr. Stephen Henson 已提交
772

773 774 775
    assert(a != b);
    assert((condition & (condition - 1)) == 0);
    assert(sizeof(BN_ULONG) >= sizeof(int));
D
Dr. Stephen Henson 已提交
776

777
    condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
D
Dr. Stephen Henson 已提交
778

779 780 781
    t = (a->top ^ b->top) & condition;
    a->top ^= t;
    b->top ^= t;
D
Dr. Stephen Henson 已提交
782 783

#define BN_CONSTTIME_SWAP(ind) \
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
        do { \
                t = (a->d[ind] ^ b->d[ind]) & condition; \
                a->d[ind] ^= t; \
                b->d[ind] ^= t; \
        } while (0)

    switch (nwords) {
    default:
        for (i = 10; i < nwords; i++)
            BN_CONSTTIME_SWAP(i);
        /* Fallthrough */
    case 10:
        BN_CONSTTIME_SWAP(9);   /* Fallthrough */
    case 9:
        BN_CONSTTIME_SWAP(8);   /* Fallthrough */
    case 8:
        BN_CONSTTIME_SWAP(7);   /* Fallthrough */
    case 7:
        BN_CONSTTIME_SWAP(6);   /* Fallthrough */
    case 6:
        BN_CONSTTIME_SWAP(5);   /* Fallthrough */
    case 5:
        BN_CONSTTIME_SWAP(4);   /* Fallthrough */
    case 4:
        BN_CONSTTIME_SWAP(3);   /* Fallthrough */
    case 3:
        BN_CONSTTIME_SWAP(2);   /* Fallthrough */
    case 2:
        BN_CONSTTIME_SWAP(1);   /* Fallthrough */
    case 1:
        BN_CONSTTIME_SWAP(0);
    }
D
Dr. Stephen Henson 已提交
816 817
#undef BN_CONSTTIME_SWAP
}
818 819 820 821

/* Bits of security, see SP800-57 */

int BN_security_bits(int L, int N)
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
{
    int secbits, bits;
    if (L >= 15360)
        secbits = 256;
    else if (L >= 7690)
        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;
}
843 844

void BN_zero_ex(BIGNUM *a)
845 846 847 848
{
    a->top = 0;
    a->neg = 0;
}
849 850

int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
851 852 853
{
    return ((a->top == 1) && (a->d[0] == w)) || ((w == 0) && (a->top == 0));
}
854 855

int BN_is_zero(const BIGNUM *a)
856 857 858
{
    return a->top == 0;
}
859 860

int BN_is_one(const BIGNUM *a)
861 862 863
{
    return BN_abs_is_word(a, 1) && !a->neg;
}
864 865

int BN_is_word(const BIGNUM *a, const BN_ULONG w)
866 867 868
{
    return BN_abs_is_word(a, w) && (!w || !a->neg);
}
869 870

int BN_is_odd(const BIGNUM *a)
871 872 873
{
    return (a->top > 0) && (a->d[0] & 1);
}
874 875

int BN_is_negative(const BIGNUM *a)
876 877 878
{
    return (a->neg != 0);
}
879

880 881 882 883 884
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);
}
885

886
void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
887 888 889 890 891 892 893
{
    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)
894
                   | BN_FLG_STATIC_DATA | flags);
895
}
896 897

BN_GENCB *BN_GENCB_new(void)
898 899
{
    BN_GENCB *ret;
900

R
Rich Salz 已提交
901
    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
902 903 904
        BNerr(BN_F_BN_GENCB_NEW, ERR_R_MALLOC_FAILURE);
        return (NULL);
    }
905

906 907
    return ret;
}
908 909

void BN_GENCB_free(BN_GENCB *cb)
910 911 912 913 914
{
    if (cb == NULL)
        return;
    OPENSSL_free(cb);
}
915 916

void BN_set_flags(BIGNUM *b, int n)
917 918 919
{
    b->flags |= n;
}
920 921

int BN_get_flags(const BIGNUM *b, int n)
922 923 924
{
    return b->flags & n;
}
925 926

/* Populate a BN_GENCB structure with an "old"-style callback */
927 928 929 930 931 932 933 934
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;
}
935 936

/* Populate a BN_GENCB structure with a "new"-style callback */
937 938 939 940 941 942 943 944
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;
}
945 946

void *BN_GENCB_get_arg(BN_GENCB *cb)
947 948 949
{
    return cb->arg;
}
950 951

BIGNUM *bn_wexpand(BIGNUM *a, int words)
952 953 954
{
    return (words <= a->dmax) ? a : bn_expand2(a, words);
}
955 956

void bn_correct_top(BIGNUM *a)
957 958 959 960 961
{
    BN_ULONG *ftl;
    int tmp_top = a->top;

    if (tmp_top > 0) {
K
Kurt Roeckx 已提交
962 963 964
        for (ftl = &(a->d[tmp_top]); tmp_top > 0; tmp_top--) {
            ftl--;
            if (*ftl != 0)
965
                break;
K
Kurt Roeckx 已提交
966
        }
967 968
        a->top = tmp_top;
    }
R
Rich Salz 已提交
969 970
    if (a->top == 0)
        a->neg = 0;
971 972
    bn_pollute(a);
}