Commit c5c6915f authored by Andy Polyakov's avatar Andy Polyakov
Browse files

bn/bn_blind.c: use Montgomery multiplication when possible.



(cherry picked from commit e02c519c)

Resolved conflicts:
	crypto/bn/bn_blind.c

Reviewed-by: default avatarPaul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/6940)
parent db09fdc1
Loading
Loading
Loading
Loading
+56 −32
Original line number Diff line number Diff line
@@ -109,11 +109,16 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
        if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
            goto err;
    } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) {
        if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx))
        if (b->m_ctx != NULL) {
            if (!bn_mul_mont_fixed_top(b->Ai, b->Ai, b->Ai, b->m_ctx, ctx)
                || !bn_mul_mont_fixed_top(b->A, b->A, b->A, b->m_ctx, ctx))
                goto err;
        if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx))
        } else {
            if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx)
                || !BN_mod_mul(b->A, b->A, b->A, b->mod, ctx))
                goto err;
        }
    }

    ret = 1;
 err:
@@ -144,13 +149,13 @@ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
    else if (!BN_BLINDING_update(b, ctx))
        return (0);

    if (r != NULL) {
        if (!BN_copy(r, b->Ai))
            ret = 0;
    }
    if (r != NULL && (BN_copy(r, b->Ai) == NULL))
        return 0;

    if (!BN_mod_mul(n, n, b->A, b->mod, ctx))
        ret = 0;
    if (b->m_ctx != NULL)
        ret = BN_mod_mul_montgomery(n, n, b->A, b->m_ctx, ctx);
    else
        ret = BN_mod_mul(n, n, b->A, b->mod, ctx);

    return ret;
}
@@ -167,14 +172,29 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,

    bn_check_top(n);

    if (r != NULL)
        ret = BN_mod_mul(n, n, r, b->mod, ctx);
    else {
        if (b->Ai == NULL) {
    if (r == NULL && (r = b->Ai) == NULL) {
        BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED);
            return (0);
        return 0;
    }
        ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);

    if (b->m_ctx != NULL) {
        /* ensure that BN_mod_mul_montgomery takes pre-defined path */
        if (n->dmax >= r->top) {
            size_t i, rtop = r->top, ntop = n->top;
            BN_ULONG mask;

            for (i = 0; i < rtop; i++) {
                mask = (BN_ULONG)0 - ((i - ntop) >> (8 * sizeof(i) - 1));
                n->d[i] &= mask;
            }
            mask = (BN_ULONG)0 - ((rtop - ntop) >> (8 * sizeof(ntop) - 1));
            /* always true, if (rtop >= ntop) n->top = r->top; */
            n->top = (int)(rtop & ~mask) | (ntop & mask);
            n->flags |= (BN_FLG_FIXED_TOP & ~mask);
        }
        ret = BN_mod_mul_montgomery(n, n, r, b->m_ctx, ctx);
    } else {
        ret = BN_mod_mul(n, n, r, b->mod, ctx);
    }

    bn_check_top(n);
@@ -253,31 +273,35 @@ BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
        int rv;
        if (!BN_rand_range(ret->A, ret->mod))
            goto err;
        if (!int_bn_mod_inverse(ret->Ai, ret->A, ret->mod, ctx, &rv)) {
        if (int_bn_mod_inverse(ret->Ai, ret->A, ret->mod, ctx, &rv))
            break;

        /*
         * this should almost never happen for good RSA keys
         */
            if (rv) {
        if (!rv)
            goto err;

        if (retry_counter-- == 0) {
                    BNerr(BN_F_BN_BLINDING_CREATE_PARAM,
                          BN_R_TOO_MANY_ITERATIONS);
            BNerr(BN_F_BN_BLINDING_CREATE_PARAM, BN_R_TOO_MANY_ITERATIONS);
            goto err;
        }
            } else
                goto err;
        } else
            break;
    } while (1);

    if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) {
        if (!ret->bn_mod_exp
            (ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
        if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
            goto err;
    } else {
        if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
            goto err;
    }

    if (ret->m_ctx != NULL) {
        if (!bn_to_mont_fixed_top(ret->Ai, ret->Ai, ret->m_ctx, ctx)
            || !bn_to_mont_fixed_top(ret->A, ret->A, ret->m_ctx, ctx))
            goto err;
    }

    return ret;
 err:
    if (b == NULL) {