crypto/dsa/dsa_key.c:114: error: BUFFER_OVERRUN_L3
  Offset: [1, +oo] Size: [0, 8388607] by call to `BN_mod_exp`.
Showing all 16 steps of the trace


crypto/dsa/dsa_key.c:75:1: Parameter `dsa->pub_key->d`
73.   }
74.   
75. > static int dsa_builtin_keygen(DSA *dsa)
76.   {
77.       int ok = 0;

crypto/dsa/dsa_key.c:114:14: Call
112.           }
113.   
114.           if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) {
                    ^
115.               BN_free(local_prk);
116.               goto err;

crypto/bn/bn_exp.c:191:1: Parameter `*r->d`
  189.   }
  190.   
  191. > int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
  192.                  BN_CTX *ctx)
  193.   {

crypto/bn/bn_exp.c:248:19: Call
  246.               && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) {
  247.               BN_ULONG A = a->d[0];
  248.               ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL);
                           ^
  249.           } else
  250.   # endif

crypto/bn/bn_exp.c:1152:1: Parameter `*rr->d`
    1150.   }
    1151.   
    1152. > int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
    1153.                            const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
    1154.   {

crypto/bn/bn_exp.c:1287:14: Call
    1285.               goto err;
    1286.       } else {
    1287.           if (!BN_from_montgomery(rr, r, mont, ctx))
                         ^
    1288.               goto err;
    1289.       }

crypto/bn/bn_mont.c:268:1: Parameter `*ret->d`
      266.   #endif                          /* MONT_WORD */
      267.   
      268. > int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
      269.                          BN_CTX *ctx)
      270.   {

crypto/bn/bn_mont.c:277:16: Call
      275.       BN_CTX_start(ctx);
      276.       if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))
      277.           retn = BN_from_montgomery_word(ret, t, mont);
                            ^
      278.       BN_CTX_end(ctx);
      279.   #else                           /* !MONT_WORD */

crypto/bn/bn_mont.c:237:14: <Offset trace>
235.               (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));
236.   
237.           for (i = 0, nl -= 4; i < nl; i += 4) {
                    ^
238.               BN_ULONG t1, t2, t3, t4;
239.   

crypto/bn/bn_mont.c:237:14: Assignment
        235.               (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));
        236.   
        237.           for (i = 0, nl -= 4; i < nl; i += 4) {
                            ^
        238.               BN_ULONG t1, t2, t3, t4;
        239.   

crypto/bn/bn_mont.c:177:1: <Length trace>
175.   
176.   #ifdef MONT_WORD
177. > static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
178.   {
179.       BIGNUM *n;

crypto/bn/bn_mont.c:177:1: Parameter `*ret->d`
        175.   
        176.   #ifdef MONT_WORD
        177. > static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
        178.   {
        179.       BIGNUM *n;

crypto/bn/bn_mont.c:214:9: Call
        212.       }
        213.   
        214.       if (bn_wexpand(ret, nl) == NULL)
                       ^
        215.           return (0);
        216.       ret->top = nl;

crypto/bn/bn_lib.c:995:1: Parameter `*a->d`
          993.   }
          994.   
          995. > BIGNUM *bn_wexpand(BIGNUM *a, int words)
          996.   {
          997.       return (words <= a->dmax) ? a : bn_expand2(a, words);

crypto/bn/bn_mont.c:219:5: Assignment
        217.       ret->neg = r->neg;
        218.   
        219.       rp = ret->d;
                   ^
        220.       ap = &(r->d[nl]);
        221.   

crypto/bn/bn_mont.c:248:13: Array access: Offset: [1, +oo] Size: [0, 8388607] by call to `BN_mod_exp` 
        246.               rp[i + 0] = t1;
        247.               ap[i + 2] = 0;
        248.               rp[i + 1] = t2;
                           ^
        249.               ap[i + 3] = 0;
        250.               rp[i + 2] = t3;

static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
{
    BIGNUM *n;
    BN_ULONG *ap, *np, *rp, n0, v, carry;
    int nl, max, i;
    n = &(mont->N);
    nl = n->top;
    if (nl == 0) {
        ret->top = 0;
        return (1);
    }
    max = (2 * nl);
    if (bn_wexpand(r, max) == NULL)
        return (0);
    r->neg ^= n->neg;
    np = n->d;
    rp = r->d;
    i = max - r->top;
    if (i)
        memset(&rp[r->top], 0, sizeof(*rp) * i);
    r->top = max;
    n0 = mont->n0[0];
    for (carry = 0, i = 0; i < nl; i++, rp++) {
        v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2);
        v = (v + carry + rp[nl]) & BN_MASK2;
        carry |= (v != rp[nl]);
        carry &= (v <= rp[nl]);
        rp[nl] = v;
    }
    if (bn_wexpand(ret, nl) == NULL)
        return (0);
    ret->top = nl;
    ret->neg = r->neg;
    rp = ret->d;
    ap = &(r->d[nl]);
# define BRANCH_FREE 1
# if BRANCH_FREE
    {
        BN_ULONG *nrp;
        size_t m;
        v = bn_sub_words(rp, ap, np, nl) - carry;
        m = (0 - (size_t)v);
        nrp =
            (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));
        for (i = 0, nl -= 4; i < nl; i += 4) {
            BN_ULONG t1, t2, t3, t4;
            t1 = nrp[i + 0];
            t2 = nrp[i + 1];
            t3 = nrp[i + 2];
            ap[i + 0] = 0;
            t4 = nrp[i + 3];
            ap[i + 1] = 0;
            rp[i + 0] = t1;
            ap[i + 2] = 0;
            rp[i + 1] = t2;
            ap[i + 3] = 0;
            rp[i + 2] = t3;
            rp[i + 3] = t4;
        }
        for (nl += 4; i < nl; i++)
            rp[i] = nrp[i], ap[i] = 0;
    }
# else
    if (bn_sub_words(rp, ap, np, nl) - carry)
        memcpy(rp, ap, nl * sizeof(BN_ULONG));
# endif
    bn_correct_top(r);
    bn_correct_top(ret);
    bn_check_top(ret);
    return (1);
}
['static int dsa_builtin_keygen(DSA *dsa)\n{\n    int ok = 0;\n    BN_CTX *ctx = NULL;\n    BIGNUM *pub_key = NULL, *priv_key = NULL;\n    if ((ctx = BN_CTX_new()) == NULL)\n        goto err;\n    if (dsa->priv_key == NULL) {\n        if ((priv_key = BN_secure_new()) == NULL)\n            goto err;\n    } else\n        priv_key = dsa->priv_key;\n    do\n        if (!BN_rand_range(priv_key, dsa->q))\n            goto err;\n    while (BN_is_zero(priv_key)) ;\n    if (dsa->pub_key == NULL) {\n        if ((pub_key = BN_new()) == NULL)\n            goto err;\n    } else\n        pub_key = dsa->pub_key;\n    {\n        BIGNUM *local_prk = NULL;\n        BIGNUM *prk;\n        if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {\n            local_prk = prk = BN_new();\n            if (local_prk == NULL)\n                goto err;\n            BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);\n        } else {\n            prk = priv_key;\n        }\n        if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) {\n            BN_free(local_prk);\n            goto err;\n        }\n        BN_free(local_prk);\n    }\n    dsa->priv_key = priv_key;\n    dsa->pub_key = pub_key;\n    ok = 1;\n err:\n    if (pub_key != dsa->pub_key)\n        BN_free(pub_key);\n    if (priv_key != dsa->priv_key)\n        BN_free(priv_key);\n    BN_CTX_free(ctx);\n    return (ok);\n}', 'int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,\n               BN_CTX *ctx)\n{\n    int ret;\n    bn_check_top(a);\n    bn_check_top(p);\n    bn_check_top(m);\n#define MONT_MUL_MOD\n#define MONT_EXP_WORD\n#define RECP_MUL_MOD\n#ifdef MONT_MUL_MOD\n    if (BN_is_odd(m)) {\n# ifdef MONT_EXP_WORD\n        if (a->top == 1 && !a->neg\n            && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) {\n            BN_ULONG A = a->d[0];\n            ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL);\n        } else\n# endif\n            ret = BN_mod_exp_mont(r, a, p, m, ctx, NULL);\n    } else\n#endif\n#ifdef RECP_MUL_MOD\n    {\n        ret = BN_mod_exp_recp(r, a, p, m, ctx);\n    }\n#else\n    {\n        ret = BN_mod_exp_simple(r, a, p, m, ctx);\n    }\n#endif\n    bn_check_top(r);\n    return (ret);\n}', 'int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,\n                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)\n{\n    BN_MONT_CTX *mont = NULL;\n    int b, bits, ret = 0;\n    int r_is_one;\n    BN_ULONG w, next_w;\n    BIGNUM *d, *r, *t;\n    BIGNUM *swap_tmp;\n#define BN_MOD_MUL_WORD(r, w, m) \\\n                (BN_mul_word(r, (w)) && \\\n                (   \\\n                        (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))\n#define BN_TO_MONTGOMERY_WORD(r, w, mont) \\\n                (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))\n    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {\n        BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);\n        return -1;\n    }\n    bn_check_top(p);\n    bn_check_top(m);\n    if (!BN_is_odd(m)) {\n        BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS);\n        return (0);\n    }\n    if (m->top == 1)\n        a %= m->d[0];\n    bits = BN_num_bits(p);\n    if (bits == 0) {\n        if (BN_is_one(m)) {\n            ret = 1;\n            BN_zero(rr);\n        } else {\n            ret = BN_one(rr);\n        }\n        return ret;\n    }\n    if (a == 0) {\n        BN_zero(rr);\n        ret = 1;\n        return ret;\n    }\n    BN_CTX_start(ctx);\n    d = BN_CTX_get(ctx);\n    r = BN_CTX_get(ctx);\n    t = BN_CTX_get(ctx);\n    if (d == NULL || r == NULL || t == 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    r_is_one = 1;\n    w = a;\n    for (b = bits - 2; b >= 0; b--) {\n        next_w = w * w;\n        if ((next_w / w) != w) {\n            if (r_is_one) {\n                if (!BN_TO_MONTGOMERY_WORD(r, w, mont))\n                    goto err;\n                r_is_one = 0;\n            } else {\n                if (!BN_MOD_MUL_WORD(r, w, m))\n                    goto err;\n            }\n            next_w = 1;\n        }\n        w = next_w;\n        if (!r_is_one) {\n            if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))\n                goto err;\n        }\n        if (BN_is_bit_set(p, b)) {\n            next_w = w * a;\n            if ((next_w / a) != w) {\n                if (r_is_one) {\n                    if (!BN_TO_MONTGOMERY_WORD(r, w, mont))\n                        goto err;\n                    r_is_one = 0;\n                } else {\n                    if (!BN_MOD_MUL_WORD(r, w, m))\n                        goto err;\n                }\n                next_w = a;\n            }\n            w = next_w;\n        }\n    }\n    if (w != 1) {\n        if (r_is_one) {\n            if (!BN_TO_MONTGOMERY_WORD(r, w, mont))\n                goto err;\n            r_is_one = 0;\n        } else {\n            if (!BN_MOD_MUL_WORD(r, w, m))\n                goto err;\n        }\n    }\n    if (r_is_one) {\n        if (!BN_one(rr))\n            goto err;\n    } else {\n        if (!BN_from_montgomery(rr, r, mont, ctx))\n            goto err;\n    }\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_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,\n                       BN_CTX *ctx)\n{\n    int retn = 0;\n#ifdef MONT_WORD\n    BIGNUM *t;\n    BN_CTX_start(ctx);\n    if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))\n        retn = BN_from_montgomery_word(ret, t, mont);\n    BN_CTX_end(ctx);\n#else\n    BIGNUM *t1, *t2;\n    BN_CTX_start(ctx);\n    t1 = BN_CTX_get(ctx);\n    t2 = BN_CTX_get(ctx);\n    if (t1 == NULL || t2 == NULL)\n        goto err;\n    if (!BN_copy(t1, a))\n        goto err;\n    BN_mask_bits(t1, mont->ri);\n    if (!BN_mul(t2, t1, &mont->Ni, ctx))\n        goto err;\n    BN_mask_bits(t2, mont->ri);\n    if (!BN_mul(t1, t2, &mont->N, ctx))\n        goto err;\n    if (!BN_add(t2, a, t1))\n        goto err;\n    if (!BN_rshift(ret, t2, mont->ri))\n        goto err;\n    if (BN_ucmp(ret, &(mont->N)) >= 0) {\n        if (!BN_usub(ret, ret, &(mont->N)))\n            goto err;\n    }\n    retn = 1;\n    bn_check_top(ret);\n err:\n    BN_CTX_end(ctx);\n#endif\n    return (retn);\n}', 'static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)\n{\n    BIGNUM *n;\n    BN_ULONG *ap, *np, *rp, n0, v, carry;\n    int nl, max, i;\n    n = &(mont->N);\n    nl = n->top;\n    if (nl == 0) {\n        ret->top = 0;\n        return (1);\n    }\n    max = (2 * nl);\n    if (bn_wexpand(r, max) == NULL)\n        return (0);\n    r->neg ^= n->neg;\n    np = n->d;\n    rp = r->d;\n    i = max - r->top;\n    if (i)\n        memset(&rp[r->top], 0, sizeof(*rp) * i);\n    r->top = max;\n    n0 = mont->n0[0];\n    for (carry = 0, i = 0; i < nl; i++, rp++) {\n        v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2);\n        v = (v + carry + rp[nl]) & BN_MASK2;\n        carry |= (v != rp[nl]);\n        carry &= (v <= rp[nl]);\n        rp[nl] = v;\n    }\n    if (bn_wexpand(ret, nl) == NULL)\n        return (0);\n    ret->top = nl;\n    ret->neg = r->neg;\n    rp = ret->d;\n    ap = &(r->d[nl]);\n# define BRANCH_FREE 1\n# if BRANCH_FREE\n    {\n        BN_ULONG *nrp;\n        size_t m;\n        v = bn_sub_words(rp, ap, np, nl) - carry;\n        m = (0 - (size_t)v);\n        nrp =\n            (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));\n        for (i = 0, nl -= 4; i < nl; i += 4) {\n            BN_ULONG t1, t2, t3, t4;\n            t1 = nrp[i + 0];\n            t2 = nrp[i + 1];\n            t3 = nrp[i + 2];\n            ap[i + 0] = 0;\n            t4 = nrp[i + 3];\n            ap[i + 1] = 0;\n            rp[i + 0] = t1;\n            ap[i + 2] = 0;\n            rp[i + 1] = t2;\n            ap[i + 3] = 0;\n            rp[i + 2] = t3;\n            rp[i + 3] = t4;\n        }\n        for (nl += 4; i < nl; i++)\n            rp[i] = nrp[i], ap[i] = 0;\n    }\n# else\n    if (bn_sub_words(rp, ap, np, nl) - carry)\n        memcpy(rp, ap, nl * sizeof(BN_ULONG));\n# endif\n    bn_correct_top(r);\n    bn_correct_top(ret);\n    bn_check_top(ret);\n    return (1);\n}', 'BIGNUM *bn_wexpand(BIGNUM *a, int words)\n{\n    return (words <= a->dmax) ? a : bn_expand2(a, words);\n}']