apps/s_client.c:412: error: BUFFER_OVERRUN_L3
  Offset: [16, +oo] (⇐ 1 + [15, +oo]) Size: [0, 8388607] by call to `srp_Verify_N_and_g`.
Showing all 34 steps of the trace


apps/s_client.c:393:9: Call
391.           BIO_printf(bio_err, "SRP parameters:\n");
392.           BIO_printf(bio_err, "\tN=");
393.           BN_print(bio_err, N);
               ^
394.           BIO_printf(bio_err, "\n\tg=");
395.           BN_print(bio_err, g);

crypto/bn/bn_print.c:348:1: Parameter `a->top`
  346.   # endif
  347.   
  348. > int BN_print(BIO *bp, const BIGNUM *a)
  349.   {
  350.       int i, j, v, z = 0;

apps/s_client.c:395:9: Call
393.           BN_print(bio_err, N);
394.           BIO_printf(bio_err, "\n\tg=");
395.           BN_print(bio_err, g);
               ^
396.           BIO_printf(bio_err, "\n");
397.       }

crypto/bn/bn_print.c:348:1: Parameter `a->top`
  346.   # endif
  347.   
  348. > int BN_print(BIO *bp, const BIGNUM *a)
  349.   {
  350.       int i, j, v, z = 0;

apps/s_client.c:399:9: Call
397.       }
398.   
399.       if (SRP_check_known_gN_param(g, N))
               ^
400.           return 1;
401.   

crypto/srp/srp_lib.c:339:1: Parameter `g->top`
  337.    * from the ietf-tls-srp draft version 8
  338.    */
  339. > char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N)
  340.   {
  341.       size_t i;

apps/s_client.c:412:13: Call
410.            * has already been tested.
411.            */
412.           if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g))
                   ^
413.               return 1;
414.       }

crypto/bn/bn_lib.c:219:9: Call
  217.       bn_check_top(a);
  218.   
  219.       if (BN_is_zero(a))
                 ^
  220.           return 0;
  221.       return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));

crypto/bn/bn_lib.c:971:1: Parameter `a->top`
    969.   }
    970.   
    971. > int BN_is_zero(const BIGNUM *a)
    972.   {
    973.       return a->top == 0;

apps/s_client.c:412:42: Call
410.            * has already been tested.
411.            */
412.           if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g))
                                                ^
413.               return 1;
414.       }

apps/s_client.c:345:1: Parameter `g->top`
  343.   # define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
  344.   
  345. > static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g)
  346.   {
  347.       BN_CTX *bn_ctx = BN_CTX_new();

apps/s_client.c:358:9: Call
  356.           r != NULL &&
  357.           /* verify g^((N-1)/2) == -1 (mod N) */
  358.           BN_mod_exp(r, g, p, N, bn_ctx) &&
                 ^
  359.           BN_add_word(r, 1) && BN_cmp(r, N) == 0;
  360.   

crypto/bn/bn_exp.c:191:1: Parameter `a->top`
    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:251:19: Call
    249.           } else
    250.   # endif
    251.               ret = BN_mod_exp_mont(r, a, p, m, ctx, NULL);
                             ^
    252.       } else
    253.   #endif

crypto/bn/bn_exp.c:401:1: Parameter `a->top`
      399.   }
      400.   
      401. > int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
      402.                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
      403.   {

crypto/bn/bn_exp.c:413:16: Call
      411.   
      412.       if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
      413.           return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
                            ^
      414.       }
      415.   

crypto/bn/bn_exp.c:693:1: Parameter `a->top`
        691.    * http://www.daemonology.net/hyperthreading-considered-harmful/)
        692.    */
        693. > int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
        694.                                 const BIGNUM *m, BN_CTX *ctx,
        695.                                 BN_MONT_CTX *in_mont)

crypto/bn/bn_exp.c:850:17: Call
        848.           if (!BN_to_montgomery(&am, &am, mont, ctx))
        849.               goto err;
        850.       } else if (!BN_to_montgomery(&am, a, mont, ctx))
                               ^
        851.           goto err;
        852.   

crypto/bn/bn_lib.c:996:1: Parameter `a->top`
          994.   }
          995.   
          996. > int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
          997.                        BN_CTX *ctx)
          998.   {

crypto/bn/bn_lib.c:999:12: Call
          997.                        BN_CTX *ctx)
          998.   {
          999.       return BN_mod_mul_montgomery(r, a, &(mont->RR), mont, ctx);
                             ^
          1000.   }
          1001.   

crypto/bn/bn_mont.c:127:1: Parameter `a->top`
            125.   #endif
            126.   
            127. > int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
            128.                             BN_MONT_CTX *mont, BN_CTX *ctx)
            129.   {

crypto/bn/bn_mont.c:154:14: Call
            152.       bn_check_top(tmp);
            153.       if (a == b) {
            154.           if (!BN_sqr(tmp, a, ctx))
                                ^
            155.               goto err;
            156.       } else {

crypto/bn/bn_sqr.c:65:1: Parameter `a->top`
              63.    * I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96
              64.    */
              65. > int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
              66.   {
              67.       int max, al;

crypto/bn/bn_sqr.c:73:5: Assignment
              71.       bn_check_top(a);
              72.   
              73.       al = a->top;
                        ^
              74.       if (al <= 0) {
              75.           r->top = 0;

crypto/bn/bn_sqr.c:122:17: Call
              120.                   if (bn_wexpand(tmp, max) == NULL)
              121.                       goto err;
              122.                   bn_sqr_normal(rr->d, a->d, al, tmp->d);
                                     ^
              123.               }
              124.           }

crypto/bn/bn_sqr.c:152:1: <Offset trace>
150.   
151.   /* tmp must have 2*n words */
152. > void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
153.   {
154.       int i, j, max;

crypto/bn/bn_sqr.c:152:1: Parameter `n`
                150.   
                151.   /* tmp must have 2*n words */
                152. > void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
                153.   {
                154.       int i, j, max;

crypto/bn/bn_sqr.c:163:5: Assignment
                161.       rp[0] = rp[max - 1] = 0;
                162.       rp++;
                163.       j = n;
                           ^
                164.   
                165.       if (--j > 0) {

crypto/bn/bn_sqr.c:165:9: Assignment
                163.       j = n;
                164.   
                165.       if (--j > 0) {
                               ^
                166.           ap++;
                167.           rp[j] = bn_mul_words(rp, ap, j, ap[-1]);

crypto/bn/bn_sqr.c:152:1: <Length trace>
150.   
151.   /* tmp must have 2*n words */
152. > void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
153.   {
154.       int i, j, max;

crypto/bn/bn_sqr.c:152:1: Parameter `*r`
                150.   
                151.   /* tmp must have 2*n words */
                152. > void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
                153.   {
                154.       int i, j, max;

crypto/bn/bn_sqr.c:160:5: Assignment
                158.       max = n * 2;
                159.       ap = a;
                160.       rp = r;
                           ^
                161.       rp[0] = rp[max - 1] = 0;
                162.       rp++;

crypto/bn/bn_sqr.c:162:5: Assignment
                160.       rp = r;
                161.       rp[0] = rp[max - 1] = 0;
                162.       rp++;
                           ^
                163.       j = n;
                164.   

crypto/bn/bn_sqr.c:167:9: Array access: Offset: [16, +oo] (⇐ 1 + [15, +oo]) Size: [0, 8388607] by call to `srp_Verify_N_and_g` 
                165.       if (--j > 0) {
                166.           ap++;
                167.           rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
                               ^
                168.           rp += 2;
                169.       }

void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
{
    int i, j, max;
    const BN_ULONG *ap;
    BN_ULONG *rp;
    max = n * 2;
    ap = a;
    rp = r;
    rp[0] = rp[max - 1] = 0;
    rp++;
    j = n;
    if (--j > 0) {
        ap++;
        rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
        rp += 2;
    }
    for (i = n - 2; i > 0; i--) {
        j--;
        ap++;
        rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
        rp += 2;
    }
    bn_add_words(r, r, r, max);
    bn_sqr_words(tmp, a, n);
    bn_add_words(r, r, tmp, max);
}
['static int ssl_srp_verify_param_cb(SSL *s, void *arg)\n{\n    SRP_ARG *srp_arg = (SRP_ARG *)arg;\n    BIGNUM *N = NULL, *g = NULL;\n    if (((N = SSL_get_srp_N(s)) == NULL) || ((g = SSL_get_srp_g(s)) == NULL))\n        return 0;\n    if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) {\n        BIO_printf(bio_err, "SRP parameters:\\n");\n        BIO_printf(bio_err, "\\tN=");\n        BN_print(bio_err, N);\n        BIO_printf(bio_err, "\\n\\tg=");\n        BN_print(bio_err, g);\n        BIO_printf(bio_err, "\\n");\n    }\n    if (SRP_check_known_gN_param(g, N))\n        return 1;\n    if (srp_arg->amp == 1) {\n        if (srp_arg->debug)\n            BIO_printf(bio_err,\n                       "SRP param N and g are not known params, going to check deeper.\\n");\n        if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g))\n            return 1;\n    }\n    BIO_printf(bio_err, "SRP param N and g rejected.\\n");\n    return 0;\n}', 'int BN_print(BIO *bp, const BIGNUM *a)\n{\n    int i, j, v, z = 0;\n    int ret = 0;\n    if ((a->neg) && (BIO_write(bp, "-", 1) != 1))\n        goto end;\n    if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1))\n        goto end;\n    for (i = a->top - 1; i >= 0; i--) {\n        for (j = BN_BITS2 - 4; j >= 0; j -= 4) {\n            v = ((int)(a->d[i] >> (long)j)) & 0x0f;\n            if (z || (v != 0)) {\n                if (BIO_write(bp, &(Hex[v]), 1) != 1)\n                    goto end;\n                z = 1;\n            }\n        }\n    }\n    ret = 1;\n end:\n    return (ret);\n}', 'char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N)\n{\n    size_t i;\n    if ((g == NULL) || (N == NULL))\n        return 0;\n    for (i = 0; i < KNOWN_GN_NUMBER; i++) {\n        if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0)\n            return knowngN[i].id;\n    }\n    return NULL;\n}', 'int BN_num_bits(const BIGNUM *a)\n{\n    int i = a->top - 1;\n    bn_check_top(a);\n    if (BN_is_zero(a))\n        return 0;\n    return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));\n}', 'int BN_is_zero(const BIGNUM *a)\n{\n    return a->top == 0;\n}', 'static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g)\n{\n    BN_CTX *bn_ctx = BN_CTX_new();\n    BIGNUM *p = BN_new();\n    BIGNUM *r = BN_new();\n    int ret =\n        g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&\n        BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&\n        p != NULL && BN_rshift1(p, N) &&\n        BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&\n        r != NULL &&\n        BN_mod_exp(r, g, p, N, bn_ctx) &&\n        BN_add_word(r, 1) && BN_cmp(r, N) == 0;\n    BN_free(r);\n    BN_free(p);\n    BN_CTX_free(bn_ctx);\n    return ret;\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(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        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_is_one(m)) {\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 (!d || !r || !val[0])\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;\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 = 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    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 ((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#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_mod(&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        bits--;\n        for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)\n            wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);\n        bn_gather5_t4(tmp.d, top, powerbuf, wvalue);\n        while (bits >= 0) {\n            if (bits < stride)\n                stride = bits + 1;\n            bits -= stride;\n            wvalue = bn_get_bits(p, bits + 1);\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        bits--;\n        for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)\n            wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);\n        bn_gather5(tmp.d, top, powerbuf, wvalue);\n        if (top & 7)\n            while (bits >= 0) {\n                for (wvalue = 0, i = 0; i < 5; i++, bits--)\n                    wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);\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                                    wvalue);\n        } else {\n            while (bits >= 0) {\n                wvalue = bn_get_bits5(p->d, bits - 4);\n                bits -= 5;\n                bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);\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        bits--;\n        for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)\n            wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);\n        if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue,\n                                            window))\n            goto err;\n        while (bits >= 0) {\n            wvalue = 0;\n            for (i = 0; i < window; i++, bits--) {\n                if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))\n                    goto err;\n                wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);\n            }\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}', 'int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,\n                     BN_CTX *ctx)\n{\n    return BN_mod_mul_montgomery(r, a, &(mont->RR), mont, ctx);\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_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)\n{\n    int max, al;\n    int ret = 0;\n    BIGNUM *tmp, *rr;\n    bn_check_top(a);\n    al = a->top;\n    if (al <= 0) {\n        r->top = 0;\n        r->neg = 0;\n        return 1;\n    }\n    BN_CTX_start(ctx);\n    rr = (a != r) ? r : BN_CTX_get(ctx);\n    tmp = BN_CTX_get(ctx);\n    if (!rr || !tmp)\n        goto err;\n    max = 2 * al;\n    if (bn_wexpand(rr, max) == NULL)\n        goto err;\n    if (al == 4) {\n#ifndef BN_SQR_COMBA\n        BN_ULONG t[8];\n        bn_sqr_normal(rr->d, a->d, 4, t);\n#else\n        bn_sqr_comba4(rr->d, a->d);\n#endif\n    } else if (al == 8) {\n#ifndef BN_SQR_COMBA\n        BN_ULONG t[16];\n        bn_sqr_normal(rr->d, a->d, 8, t);\n#else\n        bn_sqr_comba8(rr->d, a->d);\n#endif\n    } else {\n#if defined(BN_RECURSION)\n        if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {\n            BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2];\n            bn_sqr_normal(rr->d, a->d, al, t);\n        } else {\n            int j, k;\n            j = BN_num_bits_word((BN_ULONG)al);\n            j = 1 << (j - 1);\n            k = j + j;\n            if (al == j) {\n                if (bn_wexpand(tmp, k * 2) == NULL)\n                    goto err;\n                bn_sqr_recursive(rr->d, a->d, al, tmp->d);\n            } else {\n                if (bn_wexpand(tmp, max) == NULL)\n                    goto err;\n                bn_sqr_normal(rr->d, a->d, al, tmp->d);\n            }\n        }\n#else\n        if (bn_wexpand(tmp, max) == NULL)\n            goto err;\n        bn_sqr_normal(rr->d, a->d, al, tmp->d);\n#endif\n    }\n    rr->neg = 0;\n    if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))\n        rr->top = max - 1;\n    else\n        rr->top = max;\n    if (rr != r)\n        BN_copy(r, rr);\n    ret = 1;\n err:\n    bn_check_top(rr);\n    bn_check_top(tmp);\n    BN_CTX_end(ctx);\n    return (ret);\n}', 'void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)\n{\n    int i, j, max;\n    const BN_ULONG *ap;\n    BN_ULONG *rp;\n    max = n * 2;\n    ap = a;\n    rp = r;\n    rp[0] = rp[max - 1] = 0;\n    rp++;\n    j = n;\n    if (--j > 0) {\n        ap++;\n        rp[j] = bn_mul_words(rp, ap, j, ap[-1]);\n        rp += 2;\n    }\n    for (i = n - 2; i > 0; i--) {\n        j--;\n        ap++;\n        rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);\n        rp += 2;\n    }\n    bn_add_words(r, r, r, max);\n    bn_sqr_words(tmp, a, n);\n    bn_add_words(r, r, tmp, max);\n}']