crypto/dh/dh_check.c:51: error: BUFFER_OVERRUN_L3
  Offset: [1, +oo] Size: [0, 8388607] by call to `BN_mod_exp`.
Showing all 20 steps of the trace


crypto/dh/dh_check.c:37:10: Call
35.           goto err;
36.       BN_CTX_start(ctx);
37.       t1 = BN_CTX_get(ctx);
               ^
38.       if (t1 == NULL)
39.           goto err;

crypto/bn/bn_ctx.c:229:5: Call
  227.       }
  228.       /* OK, make sure the returned bignum is "zero" */
  229.       BN_zero(ret);
             ^
  230.       ctx->used++;
  231.       CTXDBG_RET(ctx, ret);

crypto/bn/bn_lib.c:463:1: Parameter `*a->d`
    461.   }
    462.   
    463. > int BN_set_word(BIGNUM *a, BN_ULONG w)
    464.   {
    465.       bn_check_top(a);

crypto/bn/bn_lib.c:466:9: Call
    464.   {
    465.       bn_check_top(a);
    466.       if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
                   ^
    467.           return (0);
    468.       a->neg = 0;

crypto/bn/bn_lcl.h:676:1: Parameter `*a->d`
      674.   int bn_probable_prime_dh_coprime(BIGNUM *rnd, int bits, BN_CTX *ctx);
      675.   
      676. > static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits)
      677.   {
      678.       if (bits > (INT_MAX - BN_BITS2 + 1))

crypto/dh/dh_check.c:51:18: Call
49.           else {
50.               /* Check g^q == 1 mod p */
51.               if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
                       ^
52.                   goto err;
53.               if (!BN_is_one(t1))

crypto/bn/bn_exp.c:90:1: Parameter `*r->d`
  88.   }
  89.   
  90. > int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
  91.                  BN_CTX *ctx)
  92.   {

crypto/bn/bn_exp.c:147:19: Call
  145.               && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) {
  146.               BN_ULONG A = a->d[0];
  147.               ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL);
                           ^
  148.           } else
  149.   # endif

crypto/bn/bn_exp.c:1089:1: Parameter `*rr->d`
    1087.   }
    1088.   
    1089. > int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
    1090.                            const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
    1091.   {

crypto/bn/bn_exp.c:1224:14: Call
    1222.               goto err;
    1223.       } else {
    1224.           if (!BN_from_montgomery(rr, r, mont, ctx))
                         ^
    1225.               goto err;
    1226.       }

crypto/bn/bn_mont.c:166:1: Parameter `*ret->d`
      164.   #endif                          /* MONT_WORD */
      165.   
      166. > int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
      167.                          BN_CTX *ctx)
      168.   {

crypto/bn/bn_mont.c:175:16: Call
      173.       BN_CTX_start(ctx);
      174.       if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))
      175.           retn = BN_from_montgomery_word(ret, t, mont);
                            ^
      176.       BN_CTX_end(ctx);
      177.   #else                           /* !MONT_WORD */

crypto/bn/bn_mont.c:135:14: <Offset trace>
133.               (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));
134.   
135.           for (i = 0, nl -= 4; i < nl; i += 4) {
                    ^
136.               BN_ULONG t1, t2, t3, t4;
137.   

crypto/bn/bn_mont.c:135:14: Assignment
        133.               (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));
        134.   
        135.           for (i = 0, nl -= 4; i < nl; i += 4) {
                            ^
        136.               BN_ULONG t1, t2, t3, t4;
        137.   

crypto/bn/bn_mont.c:75:1: <Length trace>
73.   
74.   #ifdef MONT_WORD
75. > static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
76.   {
77.       BIGNUM *n;

crypto/bn/bn_mont.c:75:1: Parameter `*ret->d`
        73.   
        74.   #ifdef MONT_WORD
        75. > static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
        76.   {
        77.       BIGNUM *n;

crypto/bn/bn_mont.c:112:9: Call
        110.       }
        111.   
        112.       if (bn_wexpand(ret, nl) == NULL)
                       ^
        113.           return (0);
        114.       ret->top = nl;

crypto/bn/bn_lib.c:1014:1: Parameter `*a->d`
          1012.   }
          1013.   
          1014. > BIGNUM *bn_wexpand(BIGNUM *a, int words)
          1015.   {
          1016.       return (words <= a->dmax) ? a : bn_expand2(a, words);

crypto/bn/bn_mont.c:117:5: Assignment
        115.       ret->neg = r->neg;
        116.   
        117.       rp = ret->d;
                   ^
        118.       ap = &(r->d[nl]);
        119.   

crypto/bn/bn_mont.c:146:13: Array access: Offset: [1, +oo] Size: [0, 8388607] by call to `BN_mod_exp` 
        144.               rp[i + 0] = t1;
        145.               ap[i + 2] = 0;
        146.               rp[i + 1] = t2;
                           ^
        147.               ap[i + 3] = 0;
        148.               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);
}
['int DH_check(const DH *dh, int *ret)\n{\n    int ok = 0;\n    BN_CTX *ctx = NULL;\n    BN_ULONG l;\n    BIGNUM *t1 = NULL, *t2 = NULL;\n    *ret = 0;\n    ctx = BN_CTX_new();\n    if (ctx == NULL)\n        goto err;\n    BN_CTX_start(ctx);\n    t1 = BN_CTX_get(ctx);\n    if (t1 == NULL)\n        goto err;\n    t2 = BN_CTX_get(ctx);\n    if (t2 == NULL)\n        goto err;\n    if (dh->q) {\n        if (BN_cmp(dh->g, BN_value_one()) <= 0)\n            *ret |= DH_NOT_SUITABLE_GENERATOR;\n        else if (BN_cmp(dh->g, dh->p) >= 0)\n            *ret |= DH_NOT_SUITABLE_GENERATOR;\n        else {\n            if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))\n                goto err;\n            if (!BN_is_one(t1))\n                *ret |= DH_NOT_SUITABLE_GENERATOR;\n        }\n        if (!BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL))\n            *ret |= DH_CHECK_Q_NOT_PRIME;\n        if (!BN_div(t1, t2, dh->p, dh->q, ctx))\n            goto err;\n        if (!BN_is_one(t2))\n            *ret |= DH_CHECK_INVALID_Q_VALUE;\n        if (dh->j && BN_cmp(dh->j, t1))\n            *ret |= DH_CHECK_INVALID_J_VALUE;\n    } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {\n        l = BN_mod_word(dh->p, 24);\n        if (l != 11)\n            *ret |= DH_NOT_SUITABLE_GENERATOR;\n    } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {\n        l = BN_mod_word(dh->p, 10);\n        if ((l != 3) && (l != 7))\n            *ret |= DH_NOT_SUITABLE_GENERATOR;\n    } else\n        *ret |= DH_UNABLE_TO_CHECK_GENERATOR;\n    if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL))\n        *ret |= DH_CHECK_P_NOT_PRIME;\n    else if (!dh->q) {\n        if (!BN_rshift1(t1, dh->p))\n            goto err;\n        if (!BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL))\n            *ret |= DH_CHECK_P_NOT_SAFE_PRIME;\n    }\n    ok = 1;\n err:\n    if (ctx != NULL) {\n        BN_CTX_end(ctx);\n        BN_CTX_free(ctx);\n    }\n    return (ok);\n}', 'BIGNUM *BN_CTX_get(BN_CTX *ctx)\n{\n    BIGNUM *ret;\n    CTXDBG_ENTRY("BN_CTX_get", ctx);\n    if (ctx->err_stack || ctx->too_many)\n        return NULL;\n    if ((ret = BN_POOL_get(&ctx->pool, ctx->flags)) == NULL) {\n        ctx->too_many = 1;\n        BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES);\n        return NULL;\n    }\n    BN_zero(ret);\n    ctx->used++;\n    CTXDBG_RET(ctx, ret);\n    return ret;\n}', 'int BN_set_word(BIGNUM *a, BN_ULONG w)\n{\n    bn_check_top(a);\n    if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)\n        return (0);\n    a->neg = 0;\n    a->d[0] = w;\n    a->top = (w ? 1 : 0);\n    bn_check_top(a);\n    return (1);\n}', 'static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits)\n{\n    if (bits > (INT_MAX - BN_BITS2 + 1))\n        return NULL;\n    if(((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax)\n        return a;\n    return bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2);\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}']