Commit 305b68f1 authored by Andy Polyakov's avatar Andy Polyakov
Browse files

bn/bn_lib.c: add BN_FLG_FIXED_TOP flag.



The new flag marks vectors that were not treated with bn_correct_top,
in other words such vectors are permitted to be zero padded. For now
it's BN_DEBUG-only flag, as initial use case for zero-padded vectors
would be controlled Montgomery multiplication/exponentiation, not
general purpose. For general purpose use another type might be more
appropriate. Advantage of this suggestion is that it's possible to
back-port it...

bn/bn_div.c: fix memory sanitizer problem.
bn/bn_sqr.c: harmonize with BN_mul.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
Reviewed-by: default avatarDavid Benjamin <davidben@google.com>
(Merged from https://github.com/openssl/openssl/pull/6662)
parent 6c90182a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -234,6 +234,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
    wnum.neg = 0;
    wnum.d = &(snum->d[loop]);
    wnum.top = div_n;
    wnum.flags = BN_FLG_STATIC_DATA;
    /*
     * only needed when BN_ucmp messes up the values between top and max
     */
+15 −2
Original line number Diff line number Diff line
@@ -141,6 +141,16 @@
 */

# ifdef BN_DEBUG
/*
 * The new BN_FLG_FIXED_TOP flag marks vectors that were not treated with
 * bn_correct_top, in other words such vectors are permitted to have zeros
 * in most significant limbs. Such vectors are used internally to achieve
 * execution time invariance for critical operations with private keys.
 * It's BN_DEBUG-only flag, because user application is not supposed to
 * observe it anyway. Moreover, optimizing compiler would actually remove
 * all operations manipulating the bit in question in non-BN_DEBUG build.
 */
#  define BN_FLG_FIXED_TOP 0x10000
#  include <assert.h>
#  ifdef BN_DEBUG_RAND
#   define bn_pollute(a) \
@@ -165,8 +175,10 @@
        do { \
                const BIGNUM *_bnum2 = (a); \
                if (_bnum2 != NULL) { \
                        assert(((_bnum2->top == 0) && !_bnum2->neg) || \
                               (_bnum2->top && (_bnum2->d[_bnum2->top - 1] != 0))); \
                        int top = _bnum2->top; \
                        assert((top == 0 && !_bnum2->neg) || \
                               (top && ((_bnum2->flags & BN_FLG_FIXED_TOP) \
                                        || _bnum2->d[top - 1] != 0))); \
                        bn_pollute(_bnum2); \
                } \
        } while(0)
@@ -185,6 +197,7 @@

# else                          /* !BN_DEBUG */

#  define BN_FLG_FIXED_TOP 0
#  define bn_pollute(a)
#  define bn_check_top(a)
#  define bn_fix_top(a)           bn_correct_top(a)
+11 −4
Original line number Diff line number Diff line
@@ -289,15 +289,17 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
    if (b->top > 0)
        memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);

    a->top = b->top;
    a->neg = b->neg;
    a->top = b->top;
    a->flags |= b->flags & BN_FLG_FIXED_TOP;
    bn_check_top(a);
    return a;
}

#define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \
                                    | BN_FLG_CONSTTIME   \
                                    | BN_FLG_SECURE))
                                    | BN_FLG_SECURE      \
                                    | BN_FLG_FIXED_TOP))
#define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED))

void BN_swap(BIGNUM *a, BIGNUM *b)
@@ -338,8 +340,9 @@ void BN_clear(BIGNUM *a)
    bn_check_top(a);
    if (a->d != NULL)
        OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax);
    a->top = 0;
    a->neg = 0;
    a->top = 0;
    a->flags &= ~BN_FLG_FIXED_TOP;
}

BN_ULONG BN_get_word(const BIGNUM *a)
@@ -360,6 +363,7 @@ int BN_set_word(BIGNUM *a, BN_ULONG w)
    a->neg = 0;
    a->d[0] = w;
    a->top = (w ? 1 : 0);
    a->flags &= ~BN_FLG_FIXED_TOP;
    bn_check_top(a);
    return 1;
}
@@ -596,6 +600,7 @@ int BN_set_bit(BIGNUM *a, int n)
        for (k = a->top; k < i + 1; k++)
            a->d[k] = 0;
        a->top = i + 1;
        a->flags &= ~BN_FLG_FIXED_TOP;
    }

    a->d[i] |= (((BN_ULONG)1) << j);
@@ -828,8 +833,9 @@ int BN_security_bits(int L, int N)

void BN_zero_ex(BIGNUM *a)
{
    a->top = 0;
    a->neg = 0;
    a->top = 0;
    a->flags &= ~BN_FLG_FIXED_TOP;
}

int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
@@ -953,5 +959,6 @@ void bn_correct_top(BIGNUM *a)
    }
    if (a->top == 0)
        a->neg = 0;
    a->flags &= ~BN_FLG_FIXED_TOP;
    bn_pollute(a);
}
+2 −8
Original line number Diff line number Diff line
@@ -82,14 +82,8 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
    }

    rr->neg = 0;
    /*
     * If the most-significant half of the top word of 'a' is zero, then the
     * square of 'a' will max-1 words.
     */
    if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
        rr->top = max - 1;
    else
    rr->top = max;
    bn_correct_top(rr);
    if (r != rr && BN_copy(r, rr) == NULL)
        goto err;