crypto/dsa/dsa_ossl.c:92: error: INTEGER_OVERFLOW_L2
  (0 - [0, max(1, `dsa->p->top`)]):unsigned64 by call to `dsa_sign_setup`.
Showing all 22 steps of the trace


crypto/dsa/dsa_ossl.c:59:1: Parameter `dsa->p->top`
57.   }
58.   
59. > static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
60.   {
61.       BIGNUM *kinv = NULL;

crypto/dsa/dsa_ossl.c:92:10: Call
90.   
91.    redo:
92.       if (!dsa_sign_setup(dsa, ctx, &kinv, &ret->r, dgst, dlen))
               ^
93.           goto err;
94.   

crypto/dsa/dsa_ossl.c:175:1: Parameter `dsa->p->top`
  173.   }
  174.   
  175. > static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
  176.                             BIGNUM **kinvp, BIGNUM **rp,
  177.                             const unsigned char *dgst, int dlen)

crypto/dsa/dsa_ossl.c:254:18: Call
  252.                   goto err;
  253.       } else {
  254.               if (!BN_mod_exp_mont(r, dsa->g, k, dsa->p, ctx, dsa->method_mont_p))
                          ^
  255.                   goto err;
  256.       }

crypto/bn/bn_exp.c:296:1: Parameter `m->top`
    294.   }
    295.   
    296. > int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
    297.                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
    298.   {

crypto/bn/bn_exp.c:310:16: Call
    308.               || BN_get_flags(a, BN_FLG_CONSTTIME) != 0
    309.               || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) {
    310.           return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
                          ^
    311.       }
    312.   

crypto/bn/bn_exp.c:745:14: Assignment
      743.           /* 2^(top*BN_BITS2) - m */
      744.           tmp.d[0] = (0 - m->d[0]) & BN_MASK2;
      745.           for (i = 1; i < top; i++)
                          ^
      746.               tmp.d[i] = (~m->d[i]) & BN_MASK2;
      747.           tmp.top = top;

crypto/bn/bn_exp.c:1062:14: Call
      1060.           bits -= window0;
      1061.           wvalue = bn_get_bits(p, bits) & wmask;
      1062.           if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue,
                           ^
      1063.                                               window))
      1064.               goto err;

crypto/bn/bn_exp.c:520:1: Parameter `top`
        518.   }
        519.   
        520. > static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
        521.                                             unsigned char *buf, int idx,
        522.                                             int window)

crypto/bn/bn_exp.c:577:5: Assignment
        575.       }
        576.   
        577.       b->top = top;
                   ^
        578.       bn_correct_top(b);
        579.       return 1;

crypto/bn/bn_exp.c:578:5: Call
        576.   
        577.       b->top = top;
        578.       bn_correct_top(b);
                   ^
        579.       return 1;
        580.   }

crypto/bn/bn_lib.c:946:1: Parameter `a->top`
          944.   }
          945.   
          946. > void bn_correct_top(BIGNUM *a)
          947.   {
          948.       BN_ULONG *ftl;

crypto/bn/bn_exp.c:1098:18: Call
      1096.   
      1097.               /* Multiply the result into the intermediate result */
      1098.               if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
                               ^
      1099.                   goto err;
      1100.           }

crypto/bn/bn_mont.c:26:1: Parameter `a->top`
        24.   #endif
        25.   
        26. > int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
        27.                             BN_MONT_CTX *mont, BN_CTX *ctx)
        28.   {

crypto/bn/bn_mont.c:56:14: Call
        54.               goto err;
        55.       } else {
        56.           if (!BN_mul(tmp, a, b, ctx))
                           ^
        57.               goto err;
        58.       }

crypto/bn/bn_mul.c:497:1: Parameter `a->top`
          495.   #endif                          /* BN_RECURSION */
          496.   
          497. > int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
          498.   {
          499.       int ret = 0;

crypto/bn/bn_mul.c:514:5: Assignment
          512.       bn_check_top(r);
          513.   
          514.       al = a->top;
                     ^
          515.       bl = b->top;
          516.   

crypto/bn/bn_mul.c:561:21: Call
          559.                */
          560.               if (i >= 0) {
          561.                   j = BN_num_bits_word((BN_ULONG)al);
                                     ^
          562.               }
          563.               if (i == -1) {

crypto/bn/bn_lib.c:89:1: <RHS trace>
87.   }
88.   
89. > int BN_num_bits_word(BN_ULONG l)
90.   {
91.       BN_ULONG x, mask;

crypto/bn/bn_lib.c:89:1: Parameter `l`
            87.   }
            88.   
            89. > int BN_num_bits_word(BN_ULONG l)
            90.   {
            91.       BN_ULONG x, mask;

crypto/bn/bn_lib.c:95:5: Assignment
            93.   
            94.   #if BN_BITS2 > 32
            95.       x = l >> 32;
                      ^
            96.       mask = (0 - x) & BN_MASK2;
            97.       mask = (0 - (mask >> (BN_BITS2 - 1)));

crypto/bn/bn_lib.c:96:5: Binary operation: (0 - [0, max(1, dsa->p->top)]):unsigned64 by call to `dsa_sign_setup` 
            94.   #if BN_BITS2 > 32
            95.       x = l >> 32;
            96.       mask = (0 - x) & BN_MASK2;
                      ^
            97.       mask = (0 - (mask >> (BN_BITS2 - 1)));
            98.       bits += 32 & mask;

int BN_num_bits_word(BN_ULONG l)
{
    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;
#endif
    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;
}
['static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)\n{\n    BIGNUM *kinv = NULL;\n    BIGNUM *m, *blind, *blindm, *tmp;\n    BN_CTX *ctx = NULL;\n    int reason = ERR_R_BN_LIB;\n    DSA_SIG *ret = NULL;\n    int rv = 0;\n    if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {\n        reason = DSA_R_MISSING_PARAMETERS;\n        goto err;\n    }\n    ret = DSA_SIG_new();\n    if (ret == NULL)\n        goto err;\n    ret->r = BN_new();\n    ret->s = BN_new();\n    if (ret->r == NULL || ret->s == NULL)\n        goto err;\n    ctx = BN_CTX_new();\n    if (ctx == NULL)\n        goto err;\n    m = BN_CTX_get(ctx);\n    blind = BN_CTX_get(ctx);\n    blindm = BN_CTX_get(ctx);\n    tmp = BN_CTX_get(ctx);\n    if (tmp == NULL)\n        goto err;\n redo:\n    if (!dsa_sign_setup(dsa, ctx, &kinv, &ret->r, dgst, dlen))\n        goto err;\n    if (dlen > BN_num_bytes(dsa->q))\n        dlen = BN_num_bytes(dsa->q);\n    if (BN_bin2bn(dgst, dlen, m) == NULL)\n        goto err;\n    do {\n        if (!BN_priv_rand(blind, BN_num_bits(dsa->q) - 1,\n                          BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))\n            goto err;\n    } while (BN_is_zero(blind));\n    BN_set_flags(blind, BN_FLG_CONSTTIME);\n    BN_set_flags(blindm, BN_FLG_CONSTTIME);\n    BN_set_flags(tmp, BN_FLG_CONSTTIME);\n    if (!BN_mod_mul(tmp, blind, dsa->priv_key, dsa->q, ctx))\n        goto err;\n    if (!BN_mod_mul(tmp, tmp, ret->r, dsa->q, ctx))\n        goto err;\n    if (!BN_mod_mul(blindm, blind, m, dsa->q, ctx))\n        goto err;\n    if (!BN_mod_add_quick(ret->s, tmp, blindm, dsa->q))\n        goto err;\n    if (!BN_mod_mul(ret->s, ret->s, kinv, dsa->q, ctx))\n        goto err;\n    if (BN_mod_inverse(blind, blind, dsa->q, ctx) == NULL)\n        goto err;\n    if (!BN_mod_mul(ret->s, ret->s, blind, dsa->q, ctx))\n        goto err;\n    if (BN_is_zero(ret->r) || BN_is_zero(ret->s))\n        goto redo;\n    rv = 1;\n err:\n    if (rv == 0) {\n        DSAerr(DSA_F_DSA_DO_SIGN, reason);\n        DSA_SIG_free(ret);\n        ret = NULL;\n    }\n    BN_CTX_free(ctx);\n    BN_clear_free(kinv);\n    return ret;\n}', 'static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,\n                          BIGNUM **kinvp, BIGNUM **rp,\n                          const unsigned char *dgst, int dlen)\n{\n    BN_CTX *ctx = NULL;\n    BIGNUM *k, *kinv = NULL, *r = *rp;\n    BIGNUM *l, *m;\n    int ret = 0;\n    int q_bits;\n    if (!dsa->p || !dsa->q || !dsa->g) {\n        DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);\n        return 0;\n    }\n    k = BN_new();\n    l = BN_new();\n    m = BN_new();\n    if (k == NULL || l == NULL || m == NULL)\n        goto err;\n    if (ctx_in == NULL) {\n        if ((ctx = BN_CTX_new()) == NULL)\n            goto err;\n    } else\n        ctx = ctx_in;\n    q_bits = BN_num_bits(dsa->q);\n    if (!BN_set_bit(k, q_bits)\n        || !BN_set_bit(l, q_bits)\n        || !BN_set_bit(m, q_bits))\n        goto err;\n    do {\n        if (dgst != NULL) {\n            if (!BN_generate_dsa_nonce(k, dsa->q, dsa->priv_key, dgst,\n                                       dlen, ctx))\n                goto err;\n        } else if (!BN_priv_rand_range(k, dsa->q))\n            goto err;\n    } while (BN_is_zero(k));\n    BN_set_flags(k, BN_FLG_CONSTTIME);\n    if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {\n        if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,\n                                    dsa->lock, dsa->p, ctx))\n            goto err;\n    }\n    if (!BN_add(l, k, dsa->q)\n        || !BN_add(m, l, dsa->q)\n        || !BN_copy(k, BN_num_bits(l) > q_bits ? l : m))\n        goto err;\n    if ((dsa)->meth->bn_mod_exp != NULL) {\n            if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx,\n                                       dsa->method_mont_p))\n                goto err;\n    } else {\n            if (!BN_mod_exp_mont(r, dsa->g, k, dsa->p, ctx, dsa->method_mont_p))\n                goto err;\n    }\n    if (!BN_mod(r, r, dsa->q, ctx))\n        goto err;\n    if ((kinv = BN_mod_inverse(NULL, k, dsa->q, ctx)) == NULL)\n        goto err;\n    BN_clear_free(*kinvp);\n    *kinvp = kinv;\n    kinv = NULL;\n    ret = 1;\n err:\n    if (!ret)\n        DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB);\n    if (ctx != ctx_in)\n        BN_CTX_free(ctx);\n    BN_clear_free(k);\n    BN_clear_free(l);\n    BN_clear_free(m);\n    return ret;\n}', 'int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,\n                    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)\n{\n    int i, j, bits, ret = 0, wstart, wend, window, wvalue;\n    int start = 1;\n    BIGNUM *d, *r;\n    const BIGNUM *aa;\n    BIGNUM *val[TABLE_SIZE];\n    BN_MONT_CTX *mont = NULL;\n    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0\n            || BN_get_flags(a, BN_FLG_CONSTTIME) != 0\n            || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) {\n        return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);\n    }\n    bn_check_top(a);\n    bn_check_top(p);\n    bn_check_top(m);\n    if (!BN_is_odd(m)) {\n        BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);\n        return 0;\n    }\n    bits = BN_num_bits(p);\n    if (bits == 0) {\n        if (BN_abs_is_word(m, 1)) {\n            ret = 1;\n            BN_zero(rr);\n        } else {\n            ret = BN_one(rr);\n        }\n        return ret;\n    }\n    BN_CTX_start(ctx);\n    d = BN_CTX_get(ctx);\n    r = BN_CTX_get(ctx);\n    val[0] = BN_CTX_get(ctx);\n    if (val[0] == NULL)\n        goto err;\n    if (in_mont != NULL)\n        mont = in_mont;\n    else {\n        if ((mont = BN_MONT_CTX_new()) == NULL)\n            goto err;\n        if (!BN_MONT_CTX_set(mont, m, ctx))\n            goto err;\n    }\n    if (a->neg || BN_ucmp(a, m) >= 0) {\n        if (!BN_nnmod(val[0], a, m, ctx))\n            goto err;\n        aa = val[0];\n    } else\n        aa = a;\n    if (BN_is_zero(aa)) {\n        BN_zero(rr);\n        ret = 1;\n        goto err;\n    }\n    if (!BN_to_montgomery(val[0], aa, mont, ctx))\n        goto err;\n    window = BN_window_bits_for_exponent_size(bits);\n    if (window > 1) {\n        if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))\n            goto err;\n        j = 1 << (window - 1);\n        for (i = 1; i < j; i++) {\n            if (((val[i] = BN_CTX_get(ctx)) == NULL) ||\n                !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx))\n                goto err;\n        }\n    }\n    start = 1;\n    wvalue = 0;\n    wstart = bits - 1;\n    wend = 0;\n#if 1\n    j = m->top;\n    if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {\n        if (bn_wexpand(r, j) == NULL)\n            goto err;\n        r->d[0] = (0 - m->d[0]) & BN_MASK2;\n        for (i = 1; i < j; i++)\n            r->d[i] = (~m->d[i]) & BN_MASK2;\n        r->top = j;\n        bn_correct_top(r);\n    } else\n#endif\n    if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))\n        goto err;\n    for (;;) {\n        if (BN_is_bit_set(p, wstart) == 0) {\n            if (!start) {\n                if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))\n                    goto err;\n            }\n            if (wstart == 0)\n                break;\n            wstart--;\n            continue;\n        }\n        j = wstart;\n        wvalue = 1;\n        wend = 0;\n        for (i = 1; i < window; i++) {\n            if (wstart - i < 0)\n                break;\n            if (BN_is_bit_set(p, wstart - i)) {\n                wvalue <<= (i - wend);\n                wvalue |= 1;\n                wend = i;\n            }\n        }\n        j = wend + 1;\n        if (!start)\n            for (i = 0; i < j; i++) {\n                if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))\n                    goto err;\n            }\n        if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))\n            goto err;\n        wstart -= wend + 1;\n        wvalue = 0;\n        start = 0;\n        if (wstart < 0)\n            break;\n    }\n#if defined(SPARC_T4_MONT)\n    if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {\n        j = mont->N.top;\n        val[0]->d[0] = 1;\n        for (i = 1; i < j; i++)\n            val[0]->d[i] = 0;\n        val[0]->top = j;\n        if (!BN_mod_mul_montgomery(rr, r, val[0], mont, ctx))\n            goto err;\n    } else\n#endif\n    if (!BN_from_montgomery(rr, r, mont, ctx))\n        goto err;\n    ret = 1;\n err:\n    if (in_mont == NULL)\n        BN_MONT_CTX_free(mont);\n    BN_CTX_end(ctx);\n    bn_check_top(rr);\n    return ret;\n}', 'int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,\n                              const BIGNUM *m, BN_CTX *ctx,\n                              BN_MONT_CTX *in_mont)\n{\n    int i, bits, ret = 0, window, wvalue, wmask, window0;\n    int top;\n    BN_MONT_CTX *mont = NULL;\n    int numPowers;\n    unsigned char *powerbufFree = NULL;\n    int powerbufLen = 0;\n    unsigned char *powerbuf = NULL;\n    BIGNUM tmp, am;\n#if defined(SPARC_T4_MONT)\n    unsigned int t4 = 0;\n#endif\n    bn_check_top(a);\n    bn_check_top(p);\n    bn_check_top(m);\n    if (!BN_is_odd(m)) {\n        BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS);\n        return 0;\n    }\n    top = m->top;\n    bits = p->top * BN_BITS2;\n    if (bits == 0) {\n        if (BN_abs_is_word(m, 1)) {\n            ret = 1;\n            BN_zero(rr);\n        } else {\n            ret = BN_one(rr);\n        }\n        return ret;\n    }\n    BN_CTX_start(ctx);\n    if (in_mont != NULL)\n        mont = in_mont;\n    else {\n        if ((mont = BN_MONT_CTX_new()) == NULL)\n            goto err;\n        if (!BN_MONT_CTX_set(mont, m, ctx))\n            goto err;\n    }\n#ifdef RSAZ_ENABLED\n    if (!a->neg) {\n        if ((16 == a->top) && (16 == p->top) && (BN_num_bits(m) == 1024)\n            && rsaz_avx2_eligible()) {\n            if (NULL == bn_wexpand(rr, 16))\n                goto err;\n            RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d,\n                                   mont->n0[0]);\n            rr->top = 16;\n            rr->neg = 0;\n            bn_correct_top(rr);\n            ret = 1;\n            goto err;\n        } else if ((8 == a->top) && (8 == p->top) && (BN_num_bits(m) == 512)) {\n            if (NULL == bn_wexpand(rr, 8))\n                goto err;\n            RSAZ_512_mod_exp(rr->d, a->d, p->d, m->d, mont->n0[0], mont->RR.d);\n            rr->top = 8;\n            rr->neg = 0;\n            bn_correct_top(rr);\n            ret = 1;\n            goto err;\n        }\n    }\n#endif\n    window = BN_window_bits_for_ctime_exponent_size(bits);\n#if defined(SPARC_T4_MONT)\n    if (window >= 5 && (top & 15) == 0 && top <= 64 &&\n        (OPENSSL_sparcv9cap_P[1] & (CFR_MONTMUL | CFR_MONTSQR)) ==\n        (CFR_MONTMUL | CFR_MONTSQR) && (t4 = OPENSSL_sparcv9cap_P[0]))\n        window = 5;\n    else\n#endif\n#if defined(OPENSSL_BN_ASM_MONT5)\n    if (window >= 5) {\n        window = 5;\n        powerbufLen += top * sizeof(mont->N.d[0]);\n    }\n#endif\n    (void)0;\n    numPowers = 1 << window;\n    powerbufLen += sizeof(m->d[0]) * (top * numPowers +\n                                      ((2 * top) >\n                                       numPowers ? (2 * top) : numPowers));\n#ifdef alloca\n    if (powerbufLen < 3072)\n        powerbufFree =\n            alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);\n    else\n#endif\n        if ((powerbufFree =\n             OPENSSL_malloc(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH))\n            == NULL)\n        goto err;\n    powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);\n    memset(powerbuf, 0, powerbufLen);\n#ifdef alloca\n    if (powerbufLen < 3072)\n        powerbufFree = NULL;\n#endif\n    tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers);\n    am.d = tmp.d + top;\n    tmp.top = am.top = 0;\n    tmp.dmax = am.dmax = top;\n    tmp.neg = am.neg = 0;\n    tmp.flags = am.flags = BN_FLG_STATIC_DATA;\n#if 1\n    if (m->d[top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {\n        tmp.d[0] = (0 - m->d[0]) & BN_MASK2;\n        for (i = 1; i < top; i++)\n            tmp.d[i] = (~m->d[i]) & BN_MASK2;\n        tmp.top = top;\n    } else\n#endif\n    if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))\n        goto err;\n    if (a->neg || BN_ucmp(a, m) >= 0) {\n        if (!BN_nnmod(&am, a, m, ctx))\n            goto err;\n        if (!BN_to_montgomery(&am, &am, mont, ctx))\n            goto err;\n    } else if (!BN_to_montgomery(&am, a, mont, ctx))\n        goto err;\n#if defined(SPARC_T4_MONT)\n    if (t4) {\n        typedef int (*bn_pwr5_mont_f) (BN_ULONG *tp, const BN_ULONG *np,\n                                       const BN_ULONG *n0, const void *table,\n                                       int power, int bits);\n        int bn_pwr5_mont_t4_8(BN_ULONG *tp, const BN_ULONG *np,\n                              const BN_ULONG *n0, const void *table,\n                              int power, int bits);\n        int bn_pwr5_mont_t4_16(BN_ULONG *tp, const BN_ULONG *np,\n                               const BN_ULONG *n0, const void *table,\n                               int power, int bits);\n        int bn_pwr5_mont_t4_24(BN_ULONG *tp, const BN_ULONG *np,\n                               const BN_ULONG *n0, const void *table,\n                               int power, int bits);\n        int bn_pwr5_mont_t4_32(BN_ULONG *tp, const BN_ULONG *np,\n                               const BN_ULONG *n0, const void *table,\n                               int power, int bits);\n        static const bn_pwr5_mont_f pwr5_funcs[4] = {\n            bn_pwr5_mont_t4_8, bn_pwr5_mont_t4_16,\n            bn_pwr5_mont_t4_24, bn_pwr5_mont_t4_32\n        };\n        bn_pwr5_mont_f pwr5_worker = pwr5_funcs[top / 16 - 1];\n        typedef int (*bn_mul_mont_f) (BN_ULONG *rp, const BN_ULONG *ap,\n                                      const void *bp, const BN_ULONG *np,\n                                      const BN_ULONG *n0);\n        int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap, const void *bp,\n                             const BN_ULONG *np, const BN_ULONG *n0);\n        int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap,\n                              const void *bp, const BN_ULONG *np,\n                              const BN_ULONG *n0);\n        int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap,\n                              const void *bp, const BN_ULONG *np,\n                              const BN_ULONG *n0);\n        int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap,\n                              const void *bp, const BN_ULONG *np,\n                              const BN_ULONG *n0);\n        static const bn_mul_mont_f mul_funcs[4] = {\n            bn_mul_mont_t4_8, bn_mul_mont_t4_16,\n            bn_mul_mont_t4_24, bn_mul_mont_t4_32\n        };\n        bn_mul_mont_f mul_worker = mul_funcs[top / 16 - 1];\n        void bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap,\n                              const void *bp, const BN_ULONG *np,\n                              const BN_ULONG *n0, int num);\n        void bn_mul_mont_t4(BN_ULONG *rp, const BN_ULONG *ap,\n                            const void *bp, const BN_ULONG *np,\n                            const BN_ULONG *n0, int num);\n        void bn_mul_mont_gather5_t4(BN_ULONG *rp, const BN_ULONG *ap,\n                                    const void *table, const BN_ULONG *np,\n                                    const BN_ULONG *n0, int num, int power);\n        void bn_flip_n_scatter5_t4(const BN_ULONG *inp, size_t num,\n                                   void *table, size_t power);\n        void bn_gather5_t4(BN_ULONG *out, size_t num,\n                           void *table, size_t power);\n        void bn_flip_t4(BN_ULONG *dst, BN_ULONG *src, size_t num);\n        BN_ULONG *np = mont->N.d, *n0 = mont->n0;\n        int stride = 5 * (6 - (top / 16 - 1));\n        for (i = am.top; i < top; i++)\n            am.d[i] = 0;\n        for (i = tmp.top; i < top; i++)\n            tmp.d[i] = 0;\n        bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 0);\n        bn_flip_n_scatter5_t4(am.d, top, powerbuf, 1);\n        if (!(*mul_worker) (tmp.d, am.d, am.d, np, n0) &&\n            !(*mul_worker) (tmp.d, am.d, am.d, np, n0))\n            bn_mul_mont_vis3(tmp.d, am.d, am.d, np, n0, top);\n        bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 2);\n        for (i = 3; i < 32; i++) {\n            if (!(*mul_worker) (tmp.d, tmp.d, am.d, np, n0) &&\n                !(*mul_worker) (tmp.d, tmp.d, am.d, np, n0))\n                bn_mul_mont_vis3(tmp.d, tmp.d, am.d, np, n0, top);\n            bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, i);\n        }\n        np = alloca(top * sizeof(BN_ULONG));\n        top /= 2;\n        bn_flip_t4(np, mont->N.d, top);\n        window0 = (bits - 1) % 5 + 1;\n        wmask = (1 << window0) - 1;\n        bits -= window0;\n        wvalue = bn_get_bits(p, bits) & wmask;\n        bn_gather5_t4(tmp.d, top, powerbuf, wvalue);\n        while (bits > 0) {\n            if (bits < stride)\n                stride = bits;\n            bits -= stride;\n            wvalue = bn_get_bits(p, bits);\n            if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))\n                continue;\n            if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))\n                continue;\n            bits += stride - 5;\n            wvalue >>= stride - 5;\n            wvalue &= 31;\n            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);\n            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);\n            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);\n            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);\n            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);\n            bn_mul_mont_gather5_t4(tmp.d, tmp.d, powerbuf, np, n0, top,\n                                   wvalue);\n        }\n        bn_flip_t4(tmp.d, tmp.d, top);\n        top *= 2;\n        tmp.top = top;\n        bn_correct_top(&tmp);\n        OPENSSL_cleanse(np, top * sizeof(BN_ULONG));\n    } else\n#endif\n#if defined(OPENSSL_BN_ASM_MONT5)\n    if (window == 5 && top > 1) {\n        void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap,\n                                 const void *table, const BN_ULONG *np,\n                                 const BN_ULONG *n0, int num, int power);\n        void bn_scatter5(const BN_ULONG *inp, size_t num,\n                         void *table, size_t power);\n        void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);\n        void bn_power5(BN_ULONG *rp, const BN_ULONG *ap,\n                       const void *table, const BN_ULONG *np,\n                       const BN_ULONG *n0, int num, int power);\n        int bn_get_bits5(const BN_ULONG *ap, int off);\n        int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap,\n                               const BN_ULONG *not_used, const BN_ULONG *np,\n                               const BN_ULONG *n0, int num);\n        BN_ULONG *n0 = mont->n0, *np;\n        for (i = am.top; i < top; i++)\n            am.d[i] = 0;\n        for (i = tmp.top; i < top; i++)\n            tmp.d[i] = 0;\n        for (np = am.d + top, i = 0; i < top; i++)\n            np[i] = mont->N.d[i];\n        bn_scatter5(tmp.d, top, powerbuf, 0);\n        bn_scatter5(am.d, am.top, powerbuf, 1);\n        bn_mul_mont(tmp.d, am.d, am.d, np, n0, top);\n        bn_scatter5(tmp.d, top, powerbuf, 2);\n# if 0\n        for (i = 3; i < 32; i++) {\n            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);\n            bn_scatter5(tmp.d, top, powerbuf, i);\n        }\n# else\n        for (i = 4; i < 32; i *= 2) {\n            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);\n            bn_scatter5(tmp.d, top, powerbuf, i);\n        }\n        for (i = 3; i < 8; i += 2) {\n            int j;\n            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);\n            bn_scatter5(tmp.d, top, powerbuf, i);\n            for (j = 2 * i; j < 32; j *= 2) {\n                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);\n                bn_scatter5(tmp.d, top, powerbuf, j);\n            }\n        }\n        for (; i < 16; i += 2) {\n            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);\n            bn_scatter5(tmp.d, top, powerbuf, i);\n            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);\n            bn_scatter5(tmp.d, top, powerbuf, 2 * i);\n        }\n        for (; i < 32; i += 2) {\n            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);\n            bn_scatter5(tmp.d, top, powerbuf, i);\n        }\n# endif\n        window0 = (bits - 1) % 5 + 1;\n        wmask = (1 << window0) - 1;\n        bits -= window0;\n        wvalue = bn_get_bits(p, bits) & wmask;\n        bn_gather5(tmp.d, top, powerbuf, wvalue);\n        if (top & 7) {\n            while (bits > 0) {\n                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);\n                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);\n                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);\n                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);\n                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);\n                bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top,\n                                    bn_get_bits5(p->d, bits -= 5));\n            }\n        } else {\n            while (bits > 0) {\n                bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top,\n                          bn_get_bits5(p->d, bits -= 5));\n            }\n        }\n        ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top);\n        tmp.top = top;\n        bn_correct_top(&tmp);\n        if (ret) {\n            if (!BN_copy(rr, &tmp))\n                ret = 0;\n            goto err;\n        }\n    } else\n#endif\n    {\n        if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, window))\n            goto err;\n        if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, window))\n            goto err;\n        if (window > 1) {\n            if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))\n                goto err;\n            if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2,\n                                              window))\n                goto err;\n            for (i = 3; i < numPowers; i++) {\n                if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))\n                    goto err;\n                if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i,\n                                                  window))\n                    goto err;\n            }\n        }\n        window0 = (bits - 1) % window + 1;\n        wmask = (1 << window0) - 1;\n        bits -= window0;\n        wvalue = bn_get_bits(p, bits) & wmask;\n        if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue,\n                                            window))\n            goto err;\n        wmask = (1 << window) - 1;\n        while (bits > 0) {\n            for (i = 0; i < window; i++)\n                if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))\n                    goto err;\n            bits -= window;\n            wvalue = bn_get_bits(p, bits) & wmask;\n            if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue,\n                                                window))\n                goto err;\n            if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))\n                goto err;\n        }\n    }\n#if defined(SPARC_T4_MONT)\n    if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {\n        am.d[0] = 1;\n        for (i = 1; i < top; i++)\n            am.d[i] = 0;\n        if (!BN_mod_mul_montgomery(rr, &tmp, &am, mont, ctx))\n            goto err;\n    } else\n#endif\n    if (!BN_from_montgomery(rr, &tmp, mont, ctx))\n        goto err;\n    ret = 1;\n err:\n    if (in_mont == NULL)\n        BN_MONT_CTX_free(mont);\n    if (powerbuf != NULL) {\n        OPENSSL_cleanse(powerbuf, powerbufLen);\n        OPENSSL_free(powerbufFree);\n    }\n    BN_CTX_end(ctx);\n    return ret;\n}', 'static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,\n                                          unsigned char *buf, int idx,\n                                          int window)\n{\n    int i, j;\n    int width = 1 << window;\n    volatile BN_ULONG *table = (volatile BN_ULONG *)buf;\n    if (bn_wexpand(b, top) == NULL)\n        return 0;\n    if (window <= 3) {\n        for (i = 0; i < top; i++, table += width) {\n            BN_ULONG acc = 0;\n            for (j = 0; j < width; j++) {\n                acc |= table[j] &\n                       ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));\n            }\n            b->d[i] = acc;\n        }\n    } else {\n        int xstride = 1 << (window - 2);\n        BN_ULONG y0, y1, y2, y3;\n        i = idx >> (window - 2);\n        idx &= xstride - 1;\n        y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1);\n        y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1);\n        y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1);\n        y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1);\n        for (i = 0; i < top; i++, table += width) {\n            BN_ULONG acc = 0;\n            for (j = 0; j < xstride; j++) {\n                acc |= ( (table[j + 0 * xstride] & y0) |\n                         (table[j + 1 * xstride] & y1) |\n                         (table[j + 2 * xstride] & y2) |\n                         (table[j + 3 * xstride] & y3) )\n                       & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));\n            }\n            b->d[i] = acc;\n        }\n    }\n    b->top = top;\n    bn_correct_top(b);\n    return 1;\n}', 'void bn_correct_top(BIGNUM *a)\n{\n    BN_ULONG *ftl;\n    int tmp_top = a->top;\n    if (tmp_top > 0) {\n        for (ftl = &(a->d[tmp_top]); tmp_top > 0; tmp_top--) {\n            ftl--;\n            if (*ftl != 0)\n                break;\n        }\n        a->top = tmp_top;\n    }\n    if (a->top == 0)\n        a->neg = 0;\n    bn_pollute(a);\n}', 'int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,\n                          BN_MONT_CTX *mont, BN_CTX *ctx)\n{\n    BIGNUM *tmp;\n    int ret = 0;\n#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)\n    int num = mont->N.top;\n    if (num > 1 && a->top == num && b->top == num) {\n        if (bn_wexpand(r, num) == NULL)\n            return 0;\n        if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {\n            r->neg = a->neg ^ b->neg;\n            r->top = num;\n            bn_correct_top(r);\n            return 1;\n        }\n    }\n#endif\n    BN_CTX_start(ctx);\n    tmp = BN_CTX_get(ctx);\n    if (tmp == NULL)\n        goto err;\n    bn_check_top(tmp);\n    if (a == b) {\n        if (!BN_sqr(tmp, a, ctx))\n            goto err;\n    } else {\n        if (!BN_mul(tmp, a, b, ctx))\n            goto err;\n    }\n#ifdef MONT_WORD\n    if (!BN_from_montgomery_word(r, tmp, mont))\n        goto err;\n#else\n    if (!BN_from_montgomery(r, tmp, mont, ctx))\n        goto err;\n#endif\n    bn_check_top(r);\n    ret = 1;\n err:\n    BN_CTX_end(ctx);\n    return ret;\n}', 'int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)\n{\n    int ret = 0;\n    int top, al, bl;\n    BIGNUM *rr;\n#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)\n    int i;\n#endif\n#ifdef BN_RECURSION\n    BIGNUM *t = NULL;\n    int j = 0, k;\n#endif\n    bn_check_top(a);\n    bn_check_top(b);\n    bn_check_top(r);\n    al = a->top;\n    bl = b->top;\n    if ((al == 0) || (bl == 0)) {\n        BN_zero(r);\n        return 1;\n    }\n    top = al + bl;\n    BN_CTX_start(ctx);\n    if ((r == a) || (r == b)) {\n        if ((rr = BN_CTX_get(ctx)) == NULL)\n            goto err;\n    } else\n        rr = r;\n#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)\n    i = al - bl;\n#endif\n#ifdef BN_MUL_COMBA\n    if (i == 0) {\n# if 0\n        if (al == 4) {\n            if (bn_wexpand(rr, 8) == NULL)\n                goto err;\n            rr->top = 8;\n            bn_mul_comba4(rr->d, a->d, b->d);\n            goto end;\n        }\n# endif\n        if (al == 8) {\n            if (bn_wexpand(rr, 16) == NULL)\n                goto err;\n            rr->top = 16;\n            bn_mul_comba8(rr->d, a->d, b->d);\n            goto end;\n        }\n    }\n#endif\n#ifdef BN_RECURSION\n    if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {\n        if (i >= -1 && i <= 1) {\n            if (i >= 0) {\n                j = BN_num_bits_word((BN_ULONG)al);\n            }\n            if (i == -1) {\n                j = BN_num_bits_word((BN_ULONG)bl);\n            }\n            j = 1 << (j - 1);\n            assert(j <= al || j <= bl);\n            k = j + j;\n            t = BN_CTX_get(ctx);\n            if (t == NULL)\n                goto err;\n            if (al > j || bl > j) {\n                if (bn_wexpand(t, k * 4) == NULL)\n                    goto err;\n                if (bn_wexpand(rr, k * 4) == NULL)\n                    goto err;\n                bn_mul_part_recursive(rr->d, a->d, b->d,\n                                      j, al - j, bl - j, t->d);\n            } else {\n                if (bn_wexpand(t, k * 2) == NULL)\n                    goto err;\n                if (bn_wexpand(rr, k * 2) == NULL)\n                    goto err;\n                bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);\n            }\n            rr->top = top;\n            goto end;\n        }\n    }\n#endif\n    if (bn_wexpand(rr, top) == NULL)\n        goto err;\n    rr->top = top;\n    bn_mul_normal(rr->d, a->d, al, b->d, bl);\n#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)\n end:\n#endif\n    rr->neg = a->neg ^ b->neg;\n    bn_correct_top(rr);\n    if (r != rr && BN_copy(r, rr) == NULL)\n        goto err;\n    ret = 1;\n err:\n    bn_check_top(r);\n    BN_CTX_end(ctx);\n    return ret;\n}', 'int BN_num_bits_word(BN_ULONG l)\n{\n    BN_ULONG x, mask;\n    int bits = (l != 0);\n#if BN_BITS2 > 32\n    x = l >> 32;\n    mask = (0 - x) & BN_MASK2;\n    mask = (0 - (mask >> (BN_BITS2 - 1)));\n    bits += 32 & mask;\n    l ^= (x ^ l) & mask;\n#endif\n    x = l >> 16;\n    mask = (0 - x) & BN_MASK2;\n    mask = (0 - (mask >> (BN_BITS2 - 1)));\n    bits += 16 & mask;\n    l ^= (x ^ l) & mask;\n    x = l >> 8;\n    mask = (0 - x) & BN_MASK2;\n    mask = (0 - (mask >> (BN_BITS2 - 1)));\n    bits += 8 & mask;\n    l ^= (x ^ l) & mask;\n    x = l >> 4;\n    mask = (0 - x) & BN_MASK2;\n    mask = (0 - (mask >> (BN_BITS2 - 1)));\n    bits += 4 & mask;\n    l ^= (x ^ l) & mask;\n    x = l >> 2;\n    mask = (0 - x) & BN_MASK2;\n    mask = (0 - (mask >> (BN_BITS2 - 1)));\n    bits += 2 & mask;\n    l ^= (x ^ l) & mask;\n    x = l >> 1;\n    mask = (0 - x) & BN_MASK2;\n    mask = (0 - (mask >> (BN_BITS2 - 1)));\n    bits += 1 & mask;\n    return bits;\n}']