Pārlūkot izejas kodu

Updating code to PuTTY 25b034ee

Source commit: 3a37adcc642933a71ce6554a76462bf55ceb5a43
Martin Prikryl 6 gadi atpakaļ
vecāks
revīzija
5dc6d9cb8e

+ 6 - 4
source/Putty.cbproj

@@ -112,6 +112,9 @@
 			<BuildOrder>5</BuildOrder>
 			<BuildOrder>25</BuildOrder>
 		</CppCompile>
+		<CppCompile Include="putty\ecc.c">
+			<BuildOrder>73</BuildOrder>
+		</CppCompile>
 		<CppCompile Include="putty\errsock.c">
 			<BuildOrder>44</BuildOrder>
 		</CppCompile>
@@ -138,6 +141,9 @@
 		<CppCompile Include="putty\miscucs.c">
 			<BuildOrder>51</BuildOrder>
 		</CppCompile>
+		<CppCompile Include="putty\mpint.c">
+			<BuildOrder>74</BuildOrder>
+		</CppCompile>
 		<CppCompile Include="putty\noshare.c">
 			<BuildOrder>41</BuildOrder>
 		</CppCompile>
@@ -215,10 +221,6 @@
 			<BuildOrder>34</BuildOrder>
 			<BuildOrder>32</BuildOrder>
 		</CppCompile>
-		<CppCompile Include="putty\sshbn.c">
-			<BuildOrder>35</BuildOrder>
-			<BuildOrder>33</BuildOrder>
-		</CppCompile>
 		<CppCompile Include="putty\sshccp.c">
 			<BuildOrder>49</BuildOrder>
 		</CppCompile>

+ 42 - 5
source/putty/ecc.c

@@ -146,7 +146,7 @@ static mp_int *ecc_weierstrass_equation_rhs(
 WeierstrassPoint *ecc_weierstrass_point_new_from_x(
     WeierstrassCurve *wc, mp_int *xorig, unsigned desired_y_parity)
 {
-    assert(wc->sc);
+    pinitassert(wc->sc);
 
     /*
      * The curve equation is y^2 = x^3 + ax + b, which is already
@@ -175,11 +175,13 @@ WeierstrassPoint *ecc_weierstrass_point_new_from_x(
      * Choose whichever of y and p-y has the specified parity (of its
      * lowest positive residue mod p).
      */
+    { // WINSCP
     mp_int *tmp = monty_export(wc->mc, y);
     unsigned flip = (mp_get_bit(tmp, 0) ^ desired_y_parity) & 1;
     mp_sub_into(tmp, wc->p, y);
     mp_select_into(y, y, tmp, flip);
     mp_free(tmp);
+    } // WINSCP
 
     return ecc_weierstrass_point_new_imported(wc, x, y);
 }
@@ -224,6 +226,7 @@ static inline void ecc_weierstrass_epilogue(
     out->X = monty_sub(wc->mc, lambda_n2, lambda_d2_xsum);
 
     /* Make the output y-coordinate */
+    { // WINSCP
     mp_int *lambda_d2_Px = monty_mul(wc->mc, lambda_d2, Px);
     mp_int *xdiff = monty_sub(wc->mc, lambda_d2_Px, out->X);
     mp_int *lambda_n_xdiff = monty_mul(wc->mc, lambda_n, xdiff);
@@ -242,6 +245,7 @@ static inline void ecc_weierstrass_epilogue(
     mp_free(lambda_n_xdiff);
     mp_free(lambda_d2_Px);
     mp_free(lambda_d3_Py);
+    } // WINSCP
 }
 
 /*
@@ -269,6 +273,7 @@ static inline void ecc_weierstrass_add_prologue(
     *Px = monty_mul(wc->mc, P->X, Qz2);
     *Py = monty_mul(wc->mc, P->Y, Qz3);
     *Qx = monty_mul(wc->mc, Q->X, Pz2);
+    { // WINSCP
     mp_int *Qy = monty_mul(wc->mc, Q->Y, Pz3);
 
     /* Common denominator */
@@ -283,6 +288,7 @@ static inline void ecc_weierstrass_add_prologue(
     mp_free(Qz2);
     mp_free(Qz3);
     mp_free(Qy);
+    } // WINSCP
 }
 
 WeierstrassPoint *ecc_weierstrass_add(WeierstrassPoint *P, WeierstrassPoint *Q)
@@ -290,6 +296,7 @@ WeierstrassPoint *ecc_weierstrass_add(WeierstrassPoint *P, WeierstrassPoint *Q)
     WeierstrassCurve *wc = P->wc;
     assert(Q->wc == wc);
 
+    { // WINSCP
     WeierstrassPoint *S = ecc_weierstrass_point_new_empty(wc);
 
     mp_int *Px, *Py, *Qx, *denom, *lambda_n, *lambda_d;
@@ -313,6 +320,7 @@ WeierstrassPoint *ecc_weierstrass_add(WeierstrassPoint *P, WeierstrassPoint *Q)
     mp_free(lambda_d);
 
     return S;
+    } // WINSCP
 }
 
 /*
@@ -375,6 +383,7 @@ WeierstrassPoint *ecc_weierstrass_add_general(
     WeierstrassCurve *wc = P->wc;
     assert(Q->wc == wc);
 
+    { // WINSCP
     WeierstrassPoint *S = ecc_weierstrass_point_new_empty(wc);
 
     /* Parameters for the epilogue, and slope of the line if P != Q */
@@ -383,10 +392,12 @@ WeierstrassPoint *ecc_weierstrass_add_general(
         P, Q, &Px, &Py, &Qx, &denom, &lambda_n, &lambda_d);
 
     /* Slope if P == Q */
+    { // WINSCP
     mp_int *lambda_n_tangent, *lambda_d_tangent;
     ecc_weierstrass_tangent_slope(P, &lambda_n_tangent, &lambda_d_tangent);
 
     /* Select between those slopes depending on whether P == Q */
+    { // WINSCP
     unsigned same_x_coord = mp_eq_integer(lambda_d, 0);
     unsigned same_y_coord = mp_eq_integer(lambda_n, 0);
     unsigned equality = same_x_coord & same_y_coord;
@@ -407,6 +418,7 @@ WeierstrassPoint *ecc_weierstrass_add_general(
      * z==0 already. Detect that and use it to normalise the other two
      * coordinates to zero.
      */
+    { // WINSCP
     unsigned output_id = mp_eq_integer(S->Z, 0);
     mp_cond_clear(S->X, output_id);
     mp_cond_clear(S->Y, output_id);
@@ -421,6 +433,10 @@ WeierstrassPoint *ecc_weierstrass_add_general(
     mp_free(lambda_d_tangent);
 
     return S;
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 WeierstrassPoint *ecc_weierstrass_multiply(WeierstrassPoint *B, mp_int *n)
@@ -438,11 +454,13 @@ WeierstrassPoint *ecc_weierstrass_multiply(WeierstrassPoint *B, mp_int *n)
      */
 
     unsigned not_started_yet = 1;
-    for (size_t bitindex = mp_max_bits(n); bitindex-- > 0 ;) {
+    size_t bitindex; // WINSCP
+    for (bitindex = mp_max_bits(n); bitindex-- > 0 ;) {
         unsigned nbit = mp_get_bit(n, bitindex);
 
         WeierstrassPoint *sum = ecc_weierstrass_add(k_B, kplus1_B);
         ecc_weierstrass_cond_swap(k_B, kplus1_B, nbit);
+        { // WINSCP
         WeierstrassPoint *other = ecc_weierstrass_double(k_B);
         ecc_weierstrass_point_free(k_B);
         ecc_weierstrass_point_free(kplus1_B);
@@ -453,6 +471,7 @@ WeierstrassPoint *ecc_weierstrass_multiply(WeierstrassPoint *B, mp_int *n)
         ecc_weierstrass_cond_overwrite(k_B, B, not_started_yet);
         ecc_weierstrass_cond_overwrite(kplus1_B, two_B, not_started_yet);
         not_started_yet &= ~nbit;
+        } // WINSCP
     }
 
     ecc_weierstrass_point_free(two_B);
@@ -543,16 +562,20 @@ MontgomeryCurve *ecc_montgomery_curve(
     mc->a = monty_import(mc->mc, a);
     mc->b = monty_import(mc->mc, b);
 
+    { // WINSCP
     mp_int *four = mp_from_integer(4);
     mp_int *fourinverse = mp_invert(four, mc->p);
     mp_int *aplus2 = mp_copy(a);
     mp_add_integer_into(aplus2, aplus2, 2);
+    { // WINSCP
     mp_int *aplus2over4 = mp_modmul(aplus2, fourinverse, mc->p);
     mc->aplus2over4 = monty_import(mc->mc, aplus2over4);
     mp_free(four);
     mp_free(fourinverse);
     mp_free(aplus2);
     mp_free(aplus2over4);
+    } // WINSCP
+    } // WINSCP
 
     return mc;
 }
@@ -631,6 +654,7 @@ MontgomeryPoint *ecc_montgomery_diff_add(
      * do a division during the main arithmetic.
      */
 
+    { // WINSCP
     MontgomeryPoint *S = ecc_montgomery_point_new_empty(mc);
 
     mp_int *Px_m_Pz = monty_sub(mc->mc, P->X, P->Z);
@@ -658,6 +682,7 @@ MontgomeryPoint *ecc_montgomery_diff_add(
     mp_free(Zpre2);
 
     return S;
+    } // WINSCP
 }
 
 MontgomeryPoint *ecc_montgomery_double(MontgomeryPoint *P)
@@ -692,6 +717,7 @@ MontgomeryPoint *ecc_montgomery_double(MontgomeryPoint *P)
     mp_int *Px_m_Pz_2 = monty_mul(mc->mc, Px_m_Pz, Px_m_Pz);
     mp_int *Px_p_Pz_2 = monty_mul(mc->mc, Px_p_Pz, Px_p_Pz);
     D->X = monty_mul(mc->mc, Px_m_Pz_2, Px_p_Pz_2);
+    { // WINSCP
     mp_int *XZ = monty_mul(mc->mc, P->X, P->Z);
     mp_int *twoXZ = monty_add(mc->mc, XZ, XZ);
     mp_int *fourXZ = monty_add(mc->mc, twoXZ, twoXZ);
@@ -708,6 +734,7 @@ MontgomeryPoint *ecc_montgomery_double(MontgomeryPoint *P)
     mp_free(fourXZ);
     mp_free(fourXZ_scaled);
     mp_free(Zpre);
+    } // WINSCP
 
     return D;
 }
@@ -759,11 +786,13 @@ MontgomeryPoint *ecc_montgomery_multiply(MontgomeryPoint *B, mp_int *n)
     MontgomeryPoint *kplus1_B = ecc_montgomery_point_copy(two_B);
 
     unsigned not_started_yet = 1;
-    for (size_t bitindex = mp_max_bits(n); bitindex-- > 0 ;) {
+    size_t bitindex; // WINSCP
+    for (bitindex = mp_max_bits(n); bitindex-- > 0 ;) {
         unsigned nbit = mp_get_bit(n, bitindex);
 
         MontgomeryPoint *sum = ecc_montgomery_diff_add(k_B, kplus1_B, B);
         ecc_montgomery_cond_swap(k_B, kplus1_B, nbit);
+        { // WINSCP
         MontgomeryPoint *other = ecc_montgomery_double(k_B);
         ecc_montgomery_point_free(k_B);
         ecc_montgomery_point_free(kplus1_B);
@@ -774,6 +803,7 @@ MontgomeryPoint *ecc_montgomery_multiply(MontgomeryPoint *B, mp_int *n)
         ecc_montgomery_cond_overwrite(k_B, B, not_started_yet);
         ecc_montgomery_cond_overwrite(kplus1_B, two_B, not_started_yet);
         not_started_yet &= ~nbit;
+        } // WINSCP
     }
 
     ecc_montgomery_point_free(two_B);
@@ -900,7 +930,7 @@ void ecc_edwards_point_free(EdwardsPoint *ep)
 EdwardsPoint *ecc_edwards_point_new_from_y(
     EdwardsCurve *ec, mp_int *yorig, unsigned desired_x_parity)
 {
-    assert(ec->sc);
+    pinitassert(ec->sc);
 
     /*
      * The curve equation is ax^2 + y^2 = 1 + dx^2y^2, which
@@ -939,11 +969,13 @@ EdwardsPoint *ecc_edwards_point_new_from_y(
      * Choose whichever of x and p-x has the specified parity (of its
      * lowest positive residue mod p).
      */
+    { // WINSCP
     mp_int *tmp = monty_export(ec->mc, x);
     unsigned flip = (mp_get_bit(tmp, 0) ^ desired_x_parity) & 1;
     mp_sub_into(tmp, ec->p, x);
     mp_select_into(x, x, tmp, flip);
     mp_free(tmp);
+    } // WINSCP
 
     return ecc_edwards_point_new_imported(ec, x, y);
 }
@@ -971,6 +1003,7 @@ EdwardsPoint *ecc_edwards_add(EdwardsPoint *P, EdwardsPoint *Q)
     EdwardsCurve *ec = P->ec;
     assert(Q->ec == ec);
 
+    { // WINSCP
     EdwardsPoint *S = ecc_edwards_point_new_empty(ec);
 
     /*
@@ -1025,6 +1058,7 @@ EdwardsPoint *ecc_edwards_add(EdwardsPoint *P, EdwardsPoint *Q)
     mp_free(H);
 
     return S;
+    } // WINSCP
 }
 
 static void ecc_edwards_normalise(EdwardsPoint *ep)
@@ -1052,11 +1086,13 @@ EdwardsPoint *ecc_edwards_multiply(EdwardsPoint *B, mp_int *n)
      */
 
     unsigned not_started_yet = 1;
-    for (size_t bitindex = mp_max_bits(n); bitindex-- > 0 ;) {
+    size_t bitindex; // WINSCP
+    for (bitindex = mp_max_bits(n); bitindex-- > 0 ;) {
         unsigned nbit = mp_get_bit(n, bitindex);
 
         EdwardsPoint *sum = ecc_edwards_add(k_B, kplus1_B);
         ecc_edwards_cond_swap(k_B, kplus1_B, nbit);
+        { // WINSCP
         EdwardsPoint *other = ecc_edwards_add(k_B, k_B);
         ecc_edwards_point_free(k_B);
         ecc_edwards_point_free(kplus1_B);
@@ -1067,6 +1103,7 @@ EdwardsPoint *ecc_edwards_multiply(EdwardsPoint *B, mp_int *n)
         ecc_edwards_cond_overwrite(k_B, B, not_started_yet);
         ecc_edwards_cond_overwrite(kplus1_B, two_B, not_started_yet);
         not_started_yet &= ~nbit;
+        } // WINSCP
     }
 
     ecc_edwards_point_free(two_B);

+ 1 - 1
source/putty/misc.h

@@ -297,7 +297,7 @@ void debug_memdump(const void *buf, int len, bool L);
 #ifdef MPEXT
 // Recent PuTTY code uses C99 standard that allows code before initialization.
 // Mostly that code are assertions. This assert implementation allows being used before code.
-#define pinitassert(P) const int __assert_dummy = 1/(P)
+#define pinitassert(P) const int __assert_dummy = 1/((int)(P))
 #endif
 
 #endif

+ 190 - 55
source/putty/mpint.c

@@ -7,6 +7,8 @@
 #include "mpint.h"
 #include "mpint_i.h"
 
+#pragma warn -ngu // WINSCP
+
 /*
  * Inline helpers to take min and max of size_t values, used
  * throughout this code.
@@ -48,7 +50,8 @@ mp_int *mp_from_integer(uintmax_t n)
 {
     mp_int *x = mp_make_sized(
         (sizeof(n) + BIGNUM_INT_BYTES - 1) / BIGNUM_INT_BYTES);
-    for (size_t i = 0; i < x->nw; i++)
+    size_t i; // WINSCP
+    for (i = 0; i < x->nw; i++)
         x->w[i] = n >> (i * BIGNUM_INT_BITS);
     return x;
 }
@@ -72,8 +75,9 @@ void mp_free(mp_int *x)
 
 void mp_dump(FILE *fp, const char *prefix, mp_int *x, const char *suffix)
 {
+    size_t i; // WINSCP
     fprintf(fp, "%s0x", prefix);
-    for (size_t i = mp_max_bytes(x); i-- > 0 ;)
+    for (i = mp_max_bytes(x); i-- > 0 ;)
         fprintf(fp, "%02X", mp_get_byte(x, i));
     fputs(suffix, fp);
 }
@@ -101,7 +105,8 @@ void mp_select_into(mp_int *dest, mp_int *src0, mp_int *src1,
                     unsigned which)
 {
     BignumInt mask = -(BignumInt)(1 & which);
-    for (size_t i = 0; i < dest->nw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < dest->nw; i++) {
         BignumInt srcword0 = mp_word(src0, i), srcword1 = mp_word(src1, i);
         dest->w[i] = srcword0 ^ ((srcword1 ^ srcword0) & mask);
     }
@@ -109,9 +114,10 @@ void mp_select_into(mp_int *dest, mp_int *src0, mp_int *src1,
 
 void mp_cond_swap(mp_int *x0, mp_int *x1, unsigned swap)
 {
-    assert(x0->nw == x1->nw);
+    pinitassert(x0->nw == x1->nw);
     BignumInt mask = -(BignumInt)(1 & swap);
-    for (size_t i = 0; i < x0->nw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < x0->nw; i++) {
         BignumInt diff = (x0->w[i] ^ x1->w[i]) & mask;
         x0->w[i] ^= diff;
         x1->w[i] ^= diff;
@@ -126,7 +132,8 @@ void mp_clear(mp_int *x)
 void mp_cond_clear(mp_int *x, unsigned clear)
 {
     BignumInt mask = ~-(BignumInt)(1 & clear);
-    for (size_t i = 0; i < x->nw; i++)
+    size_t i; // WINSCP
+    for (i = 0; i < x->nw; i++)
         x->w[i] &= mask;
 }
 
@@ -138,7 +145,8 @@ static mp_int *mp_from_bytes_int(ptrlen bytes, size_t m, size_t c)
 {
     mp_int *n = mp_make_sized(
         (bytes.len + BIGNUM_INT_BYTES - 1) / BIGNUM_INT_BYTES);
-    for (size_t i = 0; i < bytes.len; i++)
+    size_t i; // WINSCP
+    for (i = 0; i < bytes.len; i++)
         n->w[i / BIGNUM_INT_BYTES] |=
             (BignumInt)(((const unsigned char *)bytes.ptr)[m*i+c]) <<
             (8 * (i % BIGNUM_INT_BYTES));
@@ -173,14 +181,15 @@ mp_int *mp_from_decimal_pl(ptrlen decimal)
      * convergent) for log2(10), so this conservatively estimates the
      * number of bits that will be needed to store any number that can
      * be written in this many decimal digits. */
-    assert(decimal.len < (~(size_t)0) / 196);
+    pinitassert(decimal.len < (~(size_t)0) / 196);
     size_t bits = 196 * decimal.len / 59;
 
     /* Now round that up to words. */
     size_t words = bits / BIGNUM_INT_BITS + 1;
 
     mp_int *x = mp_make_sized(words);
-    for (size_t i = 0;; i++) {
+    size_t i; // WINSCP
+    for (i = 0;; i++) {
         mp_add_integer_into(x, x, ((char *)decimal.ptr)[i] - '0');
 
         if (i+1 == decimal.len)
@@ -204,11 +213,12 @@ mp_int *mp_from_decimal(const char *decimal)
  */
 mp_int *mp_from_hex_pl(ptrlen hex)
 {
-    assert(hex.len <= (~(size_t)0) / 4);
+    pinitassert(hex.len <= (~(size_t)0) / 4);
     size_t bits = hex.len * 4;
     size_t words = (bits + BIGNUM_INT_BITS - 1) / BIGNUM_INT_BITS;
     mp_int *x = mp_make_sized(words);
-    for (size_t nibble = 0; nibble < hex.len; nibble++) {
+    size_t nibble; // WINSCP
+    for (nibble = 0; nibble < hex.len; nibble++) {
         BignumInt digit = ((char *)hex.ptr)[hex.len-1 - nibble];
 
         BignumInt lmask = ~-(((digit-'a')|('f'-digit)) >> (BIGNUM_INT_BITS-1));
@@ -219,9 +229,11 @@ mp_int *mp_from_hex_pl(ptrlen hex)
         digitval ^= (digitval ^ (digit - 'A' + 10)) & umask;
         digitval &= 0xF; /* at least be _slightly_ nice about weird input */
 
+        { // WINSCP
         size_t word_idx = nibble / (BIGNUM_INT_BYTES*2);
         size_t nibble_within_word = nibble % (BIGNUM_INT_BYTES*2);
         x->w[word_idx] |= digitval << (nibble_within_word * 4);
+        } // WINSCP
     }
     return x;
 }
@@ -251,7 +263,7 @@ unsigned mp_get_bit(mp_int *x, size_t bit)
 void mp_set_bit(mp_int *x, size_t bit, unsigned val)
 {
     size_t word = bit / BIGNUM_INT_BITS;
-    assert(word < x->nw);
+    pinitassert(word < x->nw);
 
     unsigned shift = (bit % BIGNUM_INT_BITS);
 
@@ -286,7 +298,8 @@ static inline void mp_find_highest_nonzero_word_pair(
 {
     uint64_t curr_hi = 0, curr_lo = 0;
 
-    for (size_t curr_index = 0; curr_index < x->nw; curr_index++) {
+    size_t curr_index; // WINSCP
+    for (curr_index = 0; curr_index < x->nw; curr_index++) {
         BignumInt curr_word = x->w[curr_index];
         unsigned indicator = normalise_to_1(curr_word);
 
@@ -316,13 +329,15 @@ size_t mp_get_nbits(mp_int *x)
      * Find the highest nonzero word and its index.
      */
     mp_find_highest_nonzero_word_pair(x, 0, &hiword_index, &hiword64, NULL);
+    { // WINSCP
     BignumInt hiword = hiword64; /* in case BignumInt is a narrower type */
 
     /*
      * Find the index of the highest set bit within hiword.
      */
     BignumInt hibit_index = 0;
-    for (size_t i = (1 << (BIGNUM_INT_BITS_BITS-1)); i != 0; i >>= 1) {
+    size_t i; // WINSCP
+    for (i = (1 << (BIGNUM_INT_BITS_BITS-1)); i != 0; i >>= 1) {
         BignumInt shifted_word = hiword >> i;
         BignumInt indicator = (-shifted_word) >> (BIGNUM_INT_BITS-1);
         hiword ^= (shifted_word ^ hiword ) & -indicator;
@@ -333,6 +348,7 @@ size_t mp_get_nbits(mp_int *x)
      * Put together the result.
      */
     return (hiword_index << BIGNUM_INT_BITS_BITS) + hibit_index + 1;
+    } // WINSCP
 }
 
 /*
@@ -352,7 +368,8 @@ static void trim_leading_zeroes(char *buf, size_t bufsize, size_t maxtrim)
      * shift count.
      */
     if (trim > 0) {
-        for (size_t pos = trim; pos-- > 0 ;) {
+        size_t pos; // WINSCP
+        for (pos = trim; pos-- > 0 ;) {
             uint8_t diff = buf[pos] ^ '0';
             size_t mask = -((((size_t)diff) - 1) >> (BIGNUM_INT_BITS - 1));
             trim ^= (trim ^ pos) & ~mask;
@@ -364,16 +381,20 @@ static void trim_leading_zeroes(char *buf, size_t bufsize, size_t maxtrim)
      * conditional shift by 2^i bytes if bit i is set in the shift
      * count.
      */
+    { // WINSCP
     uint8_t *ubuf = (uint8_t *)buf;
-    for (size_t logd = 0; bufsize >> logd; logd++) {
+    size_t logd; // WINSCP
+    for (logd = 0; bufsize >> logd; logd++) {
         uint8_t mask = -(uint8_t)((trim >> logd) & 1);
         size_t d = (size_t)1 << logd;
-        for (size_t i = 0; i+d < bufsize; i++) {
+        size_t i; // WINSCP
+        for (i = 0; i+d < bufsize; i++) {
             uint8_t diff = mask & (ubuf[i] ^ ubuf[i+d]);
             ubuf[i] ^= diff;
             ubuf[i+d] ^= diff;
         }
     }
+    } // WINSCP
 }
 
 /*
@@ -393,8 +414,9 @@ char *mp_get_decimal(mp_int *x_orig)
      * right size.
      */
     mp_int *inv5 = mp_make_sized(x->nw);
-    assert(BIGNUM_INT_BITS % 8 == 0);
-    for (size_t i = 0; i < inv5->nw; i++)
+    pinitassert(BIGNUM_INT_BITS % 8 == 0);
+    size_t i; // WINSCP
+    for (i = 0; i < inv5->nw; i++)
         inv5->w[i] = BIGNUM_INT_MASK / 5 * 4;
     inv5->w[0]++;
 
@@ -405,6 +427,7 @@ char *mp_get_decimal(mp_int *x_orig)
      * in this many binary bits.
      */
     assert(x->nw < (~(size_t)1) / (146 * BIGNUM_INT_BITS));
+    { // WINSCP
     size_t bufsize = size_t_max(x->nw * (146 * BIGNUM_INT_BITS) / 485, 1) + 2;
     char *outbuf = snewn(bufsize, char);
     outbuf[bufsize - 1] = '\0';
@@ -414,7 +437,9 @@ char *mp_get_decimal(mp_int *x_orig)
      * significant upwards, so that we write to outbuf in reverse
      * order.
      */
-    for (size_t pos = bufsize - 1; pos-- > 0 ;) {
+    { // WINSCP
+    size_t pos; // WINSCP
+    for (pos = bufsize - 1; pos-- > 0 ;) {
         /*
          * Find the current residue mod 10. We do this by first
          * summing the bytes of the number, with all but the lowest
@@ -426,8 +451,10 @@ char *mp_get_decimal(mp_int *x_orig)
          * input-dependent timing.
          */
         uint32_t low_digit = 0, maxval = 0, mult = 1;
-        for (size_t i = 0; i < x->nw; i++) {
-            for (unsigned j = 0; j < BIGNUM_INT_BYTES; j++) {
+        size_t i; // WINSCP
+        for (i = 0; i < x->nw; i++) {
+            unsigned j; // WINSCP
+            for (j = 0; j < BIGNUM_INT_BYTES; j++) {
                 low_digit += mult * (0xFF & (x->w[i] >> (8*j)));
                 maxval += mult * 0xFF;
                 mult = 6;
@@ -475,6 +502,8 @@ char *mp_get_decimal(mp_int *x_orig)
 
     trim_leading_zeroes(outbuf, bufsize, bufsize - 2);
     return outbuf;
+    } // WINSCP
+    } // WINSCP
 }
 
 /*
@@ -487,9 +516,10 @@ static char *mp_get_hex_internal(mp_int *x, uint8_t letter_offset)
     size_t nibbles = x->nw * BIGNUM_INT_BYTES * 2;
     size_t bufsize = nibbles + 1;
     char *outbuf = snewn(bufsize, char);
+    size_t nibble; // WINSCP
     outbuf[nibbles] = '\0';
 
-    for (size_t nibble = 0; nibble < nibbles; nibble++) {
+    for (nibble = 0; nibble < nibbles; nibble++) {
         size_t word_idx = nibble / (BIGNUM_INT_BYTES*2);
         size_t nibble_within_word = nibble % (BIGNUM_INT_BYTES*2);
         uint8_t digitval = 0xF & (x->w[word_idx] >> (nibble_within_word * 4));
@@ -526,9 +556,10 @@ void BinarySink_put_mp_ssh1(BinarySink *bs, mp_int *x)
     size_t bits = mp_get_nbits(x);
     size_t bytes = (bits + 7) / 8;
 
+    size_t i; // WINSCP
     assert(bits < 0x10000);
     put_uint16(bs, bits);
-    for (size_t i = bytes; i-- > 0 ;)
+    for (i = bytes; i-- > 0 ;)
         put_byte(bs, mp_get_byte(x, i));
 }
 
@@ -536,8 +567,9 @@ void BinarySink_put_mp_ssh2(BinarySink *bs, mp_int *x)
 {
     size_t bytes = (mp_get_nbits(x) + 8) / 8;
 
+    size_t i; // WINSCP
     put_uint32(bs, bytes);
-    for (size_t i = bytes; i-- > 0 ;)
+    for (i = bytes; i-- > 0 ;)
         put_byte(bs, mp_get_byte(x, i));
 }
 
@@ -601,10 +633,12 @@ static mp_int mp_make_alias(mp_int *in, size_t offset, size_t len)
     if (len > in->nw - offset)
         len = in->nw - offset;
 
+    { // WINSCP
     mp_int toret;
     toret.nw = len;
     toret.w = in->w + offset;
     return toret;
+    } // WINSCP
 }
 
 /*
@@ -623,7 +657,7 @@ static mp_int mp_make_alias(mp_int *in, size_t offset, size_t len)
  */
 static mp_int mp_alloc_from_scratch(mp_int *pool, size_t len)
 {
-    assert(len <= pool->nw);
+    pinitassert(len <= pool->nw);
     mp_int toret = mp_make_alias(pool, 0, len);
     *pool = mp_make_alias(pool, len, pool->nw);
     return toret;
@@ -648,7 +682,8 @@ static BignumCarry mp_add_masked_into(
     BignumInt *w_out, size_t rw, mp_int *a, mp_int *b,
     BignumInt b_and, BignumInt b_xor, BignumCarry carry)
 {
-    for (size_t i = 0; i < rw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < rw; i++) {
         BignumInt aword = mp_word(a, i), bword = mp_word(b, i), out;
         bword = (bword & b_and) ^ b_xor;
         BignumADC(out, carry, aword, bword, carry);
@@ -680,7 +715,8 @@ static void mp_cond_negate(mp_int *r, mp_int *x, unsigned yes)
 {
     BignumCarry carry = yes;
     BignumInt flip = -(BignumInt)yes;
-    for (size_t i = 0; i < r->nw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < r->nw; i++) {
         BignumInt xword = mp_word(x, i);
         xword ^= flip;
         BignumADC(r->w[i], carry, 0, xword, carry);
@@ -695,7 +731,8 @@ static BignumCarry mp_add_masked_integer_into(
     BignumInt *w_out, size_t rw, mp_int *a, uintmax_t b,
     BignumInt b_and, BignumInt b_xor, BignumCarry carry)
 {
-    for (size_t i = 0; i < rw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < rw; i++) {
         BignumInt aword = mp_word(a, i);
         size_t shift = i * BIGNUM_INT_BITS;
         BignumInt bword = shift < BIGNUM_INT_BYTES ? b >> shift : 0;
@@ -728,8 +765,9 @@ static void mp_add_integer_into_shifted_by_words(
 {
     unsigned indicator = 0;
     BignumCarry carry = 0;
+    size_t i; // WINSCP
 
-    for (size_t i = 0; i < r->nw; i++) {
+    for (i = 0; i < r->nw; i++) {
         /* indicator becomes 1 when we reach the index that the least
          * significant bits of n want to be placed at, and it stays 1
          * thereafter. */
@@ -738,21 +776,26 @@ static void mp_add_integer_into_shifted_by_words(
         /* If indicator is 1, we add the low bits of n into r, and
          * shift n down. If it's 0, we add zero bits into r, and
          * leave n alone. */
+        { // WINSCP
         BignumInt bword = n & -(BignumInt)indicator;
         uintmax_t new_n = (BIGNUM_INT_BITS < 64 ? n >> BIGNUM_INT_BITS : 0);
         n ^= (n ^ new_n) & -(uintmax_t)indicator;
 
+        { // WINSCP
         BignumInt aword = mp_word(a, i);
         BignumInt out;
         BignumADC(out, carry, aword, bword, carry);
         r->w[i] = out;
+        } // WINSCP
+        } // WINSCP
     }
 }
 
 void mp_mul_integer_into(mp_int *r, mp_int *a, uint16_t n)
 {
     BignumInt carry = 0, mult = n;
-    for (size_t i = 0; i < r->nw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < r->nw; i++) {
         BignumInt aword = mp_word(a, i);
         BignumMULADD(carry, r->w[i], aword, mult, carry);
     }
@@ -784,7 +827,8 @@ unsigned mp_cmp_hs(mp_int *a, mp_int *b)
 unsigned mp_hs_integer(mp_int *x, uintmax_t n)
 {
     BignumInt carry = 1;
-    for (size_t i = 0; i < x->nw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < x->nw; i++) {
         size_t shift = i * BIGNUM_INT_BITS;
         BignumInt nword = shift < BIGNUM_INT_BYTES ? n >> shift : 0;
         BignumInt dummy_out;
@@ -802,7 +846,8 @@ unsigned mp_hs_integer(mp_int *x, uintmax_t n)
 unsigned mp_cmp_eq(mp_int *a, mp_int *b)
 {
     BignumInt diff = 0;
-    for (size_t i = 0, limit = size_t_max(a->nw, b->nw); i < limit; i++)
+    size_t i, limit; // WINSCP
+    for (i = 0, limit = size_t_max(a->nw, b->nw); i < limit; i++)
         diff |= mp_word(a, i) ^ mp_word(b, i);
     return 1 ^ normalise_to_1(diff);   /* return 1 if diff _is_ zero */
 }
@@ -810,7 +855,8 @@ unsigned mp_cmp_eq(mp_int *a, mp_int *b)
 unsigned mp_eq_integer(mp_int *x, uintmax_t n)
 {
     BignumInt diff = 0;
-    for (size_t i = 0; i < x->nw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < x->nw; i++) {
         size_t shift = i * BIGNUM_INT_BITS;
         BignumInt nword = shift < BIGNUM_INT_BYTES ? n >> shift : 0;
         diff |= x->w[i] ^ nword;
@@ -854,15 +900,19 @@ static void mp_mul_add_simple(mp_int *r, mp_int *a, mp_int *b)
 {
     BignumInt *aend = a->w + a->nw, *bend = b->w + b->nw, *rend = r->w + r->nw;
 
-    for (BignumInt *ap = a->w, *rp = r->w;
+    BignumInt *ap, *rp; // WINSCP
+    for (ap = a->w, rp = r->w;
          ap < aend && rp < rend; ap++, rp++) {
 
         BignumInt adata = *ap, carry = 0, *rq = rp;
 
-        for (BignumInt *bp = b->w; bp < bend && rq < rend; bp++, rq++) {
+        { // WINSCP
+        BignumInt *bp; // WINSCP
+        for (bp = b->w; bp < bend && rq < rend; bp++, rq++) {
             BignumInt bdata = bp < bend ? *bp : 0;
             BignumMULADD2(carry, *rq, adata, bdata, *rq, carry);
         }
+        } // WINSCP
 
         for (; rq < rend; rq++)
             BignumADC(*rq, carry, 0, *rq, carry);
@@ -956,6 +1006,7 @@ static void mp_mul_internal(mp_int *r, mp_int *a, mp_int *b, mp_int scratch)
      * it would take if we just did a long conventional multiply.
      */
 
+    { // WINSCP
     /* Break up the input as botlen + toplen, with botlen >= toplen.
      * The 'base' D is equal to 2^{botlen * BIGNUM_INT_BITS}. */
     size_t toplen = inlen / 2;
@@ -995,12 +1046,14 @@ static void mp_mul_internal(mp_int *r, mp_int *a, mp_int *b, mp_int scratch)
         return;
     }
 
+    { // WINSCP
     /* a0+a1 and b0+b1 */
     mp_int asum = mp_alloc_from_scratch(&scratch, botlen+1);
     mp_int bsum = mp_alloc_from_scratch(&scratch, botlen+1);
     mp_add_into(&asum, &a0, &a1);
     mp_add_into(&bsum, &b0, &b1);
 
+    { // WINSCP
     /* Their product */
     mp_int product = mp_alloc_from_scratch(&scratch, botlen*2+1);
     mp_mul_internal(&product, &asum, &bsum, scratch);
@@ -1011,6 +1064,9 @@ static void mp_mul_internal(mp_int *r, mp_int *a, mp_int *b, mp_int scratch)
 
     /* And add it in with the right offset. */
     mp_add_into(&r1, &r1, &product);
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 void mp_mul_into(mp_int *r, mp_int *a, mp_int *b)
@@ -1032,7 +1088,8 @@ void mp_lshift_fixed_into(mp_int *r, mp_int *a, size_t bits)
     size_t words = bits / BIGNUM_INT_BITS;
     size_t bitoff = bits % BIGNUM_INT_BITS;
 
-    for (size_t i = 0; i < r->nw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < r->nw; i++) {
         if (i < words) {
             r->w[i] = 0;
         } else {
@@ -1052,7 +1109,8 @@ void mp_rshift_fixed_into(mp_int *r, mp_int *a, size_t bits)
     size_t words = bits / BIGNUM_INT_BITS;
     size_t bitoff = bits % BIGNUM_INT_BITS;
 
-    for (size_t i = 0; i < r->nw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < r->nw; i++) {
         r->w[i] = mp_word(a, i + words);
         if (bitoff != 0) {
             r->w[i] >>= bitoff;
@@ -1084,13 +1142,15 @@ mp_int *mp_rshift_safe(mp_int *x, size_t bits)
 
     mp_int *r = mp_copy(x);
 
+    unsigned bit; // WINSCP
     unsigned clear = (r->nw - wordshift) >> (CHAR_BIT * sizeof(size_t) - 1);
     mp_cond_clear(r, clear);
 
-    for (unsigned bit = 0; r->nw >> bit; bit++) {
+    for (bit = 0; r->nw >> bit; bit++) {
         size_t word_offset = 1 << bit;
         BignumInt mask = -(BignumInt)((wordshift >> bit) & 1);
-        for (size_t i = 0; i < r->nw; i++) {
+        size_t i; // WINSCP
+        for (i = 0; i < r->nw; i++) {
             BignumInt w = mp_word(r, i + word_offset);
             r->w[i] ^= (r->w[i] ^ w) & mask;
         }
@@ -1104,15 +1164,20 @@ mp_int *mp_rshift_safe(mp_int *x, size_t bits)
      * time-constant. If they're not, I could replace this with
      * another loop over bit positions.
      */
+    { // WINSCP
     size_t upshift = BIGNUM_INT_BITS - bitshift;
     size_t no_shift = (upshift >> BIGNUM_INT_BITS_BITS);
     upshift &= ~-(size_t)no_shift;
+    { // WINSCP
     BignumInt upshifted_mask = ~-(BignumInt)no_shift;
 
-    for (size_t i = 0; i < r->nw; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < r->nw; i++) {
         r->w[i] = (r->w[i] >> bitshift) |
             ((mp_word(r, i+1) << upshift) & upshifted_mask);
     }
+    } // WINSCP
+    } // WINSCP
 
     return r;
 }
@@ -1139,6 +1204,7 @@ mp_int *mp_invert_mod_2to(mp_int *x, size_t p)
     assert(x->w[0] & 1);
     assert(p > 0);
 
+    { // WINSCP
     size_t rw = (p + BIGNUM_INT_BITS - 1) / BIGNUM_INT_BITS;
     mp_int *r = mp_make_sized(rw);
 
@@ -1147,10 +1213,11 @@ mp_int *mp_invert_mod_2to(mp_int *x, size_t p)
     mp_int scratch_per_iter = *scratch_orig;
     mp_int mul_scratch = mp_alloc_from_scratch(
         &scratch_per_iter, mul_scratchsize);
+    size_t b; // WINSCP
 
     r->w[0] = 1;
 
-    for (size_t b = 1; b < p; b <<= 1) {
+    for (b = 1; b < p; b <<= 1) {
         /*
          * In each step of this iteration, we have the inverse of x
          * mod 2^b, and we want the inverse of x mod 2^{2b}.
@@ -1185,16 +1252,20 @@ mp_int *mp_invert_mod_2to(mp_int *x, size_t p)
         mp_int x0 = mp_alloc_from_scratch(&scratch_this_iter, Bw);
         mp_copy_into(&x0, x);
         mp_reduce_mod_2to(&x0, b);
+        { // WINSCP
         mp_int r0 = mp_make_alias(r, 0, Bw);
         mp_int Kshift = mp_alloc_from_scratch(&scratch_this_iter, B2w);
         mp_mul_internal(&Kshift, &x0, &r0, mul_scratch);
+        { // WINSCP
         mp_int K = mp_alloc_from_scratch(&scratch_this_iter, Bw);
         mp_rshift_fixed_into(&K, &Kshift, b);
 
         /* Now compute the product r_0 x_1, reusing the space of Kshift. */
+        { // WINSCP
         mp_int x1 = mp_alloc_from_scratch(&scratch_this_iter, Bw);
         mp_rshift_fixed_into(&x1, x, b);
         mp_reduce_mod_2to(&x1, b);
+        { // WINSCP
         mp_int r0x1 = mp_make_alias(&Kshift, 0, Bw);
         mp_mul_internal(&r0x1, &r0, &x1, mul_scratch);
 
@@ -1205,6 +1276,7 @@ mp_int *mp_invert_mod_2to(mp_int *x, size_t p)
         mp_neg_into(&r0x1, &r0x1);
 
         /* Multiply by r_0. */
+        { // WINSCP
         mp_int r1 = mp_alloc_from_scratch(&scratch_this_iter, Bw);
         mp_mul_internal(&r1, &r0, &r0x1, mul_scratch);
         mp_reduce_mod_2to(&r1, b);
@@ -1212,9 +1284,16 @@ mp_int *mp_invert_mod_2to(mp_int *x, size_t p)
         /* That's our r_1, so add it on to r_0 to get the full inverse
          * output from this iteration. */
         mp_lshift_fixed_into(&K, &r1, (b % BIGNUM_INT_BITS));
+        { // WINSCP
         size_t Bpos = b / BIGNUM_INT_BITS;
         mp_int r1_position = mp_make_alias(r, Bpos, B2w-Bpos);
         mp_add_into(&r1_position, &r1_position, &K);
+        } // WINSCP
+        } // WINSCP
+        } // WINSCP
+        } // WINSCP
+        } // WINSCP
+        } // WINSCP
     }
 
     /* Finally, reduce mod the precise desired number of bits. */
@@ -1222,6 +1301,7 @@ mp_int *mp_invert_mod_2to(mp_int *x, size_t p)
 
     mp_free(scratch_orig);
     return r;
+    } // WINSCP
 }
 
 static size_t monty_scratch_size(MontyContext *mc)
@@ -1242,22 +1322,26 @@ MontyContext *monty_new(mp_int *modulus)
     mc->minus_minv_mod_r = mp_invert_mod_2to(mc->m, mc->rbits);
     mp_neg_into(mc->minus_minv_mod_r, mc->minus_minv_mod_r);
 
+    { // WINSCP
+    size_t j; // WINSCP
     mp_int *r = mp_make_sized(mc->rw + 1);
     r->w[mc->rw] = 1;
     mc->powers_of_r_mod_m[0] = mp_mod(r, mc->m);
     mp_free(r);
 
-    for (size_t j = 1; j < lenof(mc->powers_of_r_mod_m); j++)
+    for (j = 1; j < lenof(mc->powers_of_r_mod_m); j++)
         mc->powers_of_r_mod_m[j] = mp_modmul(
             mc->powers_of_r_mod_m[0], mc->powers_of_r_mod_m[j-1], mc->m);
 
     mc->scratch = mp_make_sized(monty_scratch_size(mc));
 
     return mc;
+    } // WINSCP
 }
 
 MontyContext *monty_copy(MontyContext *orig)
 {
+    size_t j; // WINSCP
     MontyContext *mc = snew(MontyContext);
 
     mc->rw = orig->rw;
@@ -1265,7 +1349,7 @@ MontyContext *monty_copy(MontyContext *orig)
     mc->rbits = orig->rbits;
     mc->m = mp_copy(orig->m);
     mc->minus_minv_mod_r = mp_copy(orig->minus_minv_mod_r);
-    for (size_t j = 0; j < 3; j++)
+    for (j = 0; j < 3; j++)
         mc->powers_of_r_mod_m[j] = mp_copy(orig->powers_of_r_mod_m[j]);
     mc->scratch = mp_make_sized(monty_scratch_size(mc));
     return mc;
@@ -1273,8 +1357,9 @@ MontyContext *monty_copy(MontyContext *orig)
 
 void monty_free(MontyContext *mc)
 {
+    size_t j; // WINSCP
     mp_free(mc->m);
-    for (size_t j = 0; j < 3; j++)
+    for (j = 0; j < 3; j++)
         mp_free(mc->powers_of_r_mod_m[j]);
     mp_free(mc->minus_minv_mod_r);
     mp_free(mc->scratch);
@@ -1312,6 +1397,7 @@ static mp_int monty_reduce_internal(MontyContext *mc, mp_int *x, mp_int scratch)
     mp_mul_internal(&k, &x_lo, mc->minus_minv_mod_r, scratch);
 
     /* m times that, i.e. the number we want to add to x */
+    { // WINSCP
     mp_int mk = mp_alloc_from_scratch(&scratch, mc->pw);
     mp_mul_internal(&mk, mc->m, &k, scratch);
 
@@ -1319,6 +1405,7 @@ static mp_int monty_reduce_internal(MontyContext *mc, mp_int *x, mp_int scratch)
     mp_add_into(&mk, x, &mk);
 
     /* Reduce mod r, by simply making an alias to the upper words of x */
+    { // WINSCP
     mp_int toret = mp_make_alias(&mk, mc->rw, mk.nw - mc->rw);
 
     /*
@@ -1331,6 +1418,8 @@ static mp_int monty_reduce_internal(MontyContext *mc, mp_int *x, mp_int scratch)
      */
     mp_cond_sub_into(&toret, &toret, mc->m, mp_cmp_hs(&toret, mc->m));
     return toret;
+    } // WINSCP
+    } // WINSCP
 }
 
 void monty_mul_into(MontyContext *mc, mp_int *r, mp_int *x, mp_int *y)
@@ -1338,12 +1427,16 @@ void monty_mul_into(MontyContext *mc, mp_int *r, mp_int *x, mp_int *y)
     assert(x->nw <= mc->rw);
     assert(y->nw <= mc->rw);
 
+    { // WINSCP
     mp_int scratch = *mc->scratch;
     mp_int tmp = mp_alloc_from_scratch(&scratch, 2*mc->rw);
     mp_mul_into(&tmp, x, y);
+    { // WINSCP
     mp_int reduced = monty_reduce_internal(mc, &tmp, scratch);
     mp_copy_into(r, &reduced);
     mp_clear(mc->scratch);
+    } // WINSCP
+    } // WINSCP
 }
 
 mp_int *monty_mul(MontyContext *mc, mp_int *x, mp_int *y)
@@ -1398,7 +1491,7 @@ mp_int *monty_import(MontyContext *mc, mp_int *x)
  */
 void monty_export_into(MontyContext *mc, mp_int *r, mp_int *x)
 {
-    assert(x->nw <= 2*mc->rw);
+    pinitassert(x->nw <= 2*mc->rw);
     mp_int reduced = monty_reduce_internal(mc, x, *mc->scratch);
     mp_copy_into(r, &reduced);
     mp_clear(mc->scratch);
@@ -1456,6 +1549,7 @@ mp_int *mp_modpow(mp_int *base, mp_int *exponent, mp_int *modulus)
     assert(modulus->nw > 0);
     assert(modulus->w[0] & 1);
 
+    { // WINSCP
     MontyContext *mc = monty_new(modulus);
     mp_int *m_base = monty_import(mc, base);
     mp_int *m_out = monty_pow(mc, m_base, exponent);
@@ -1464,6 +1558,7 @@ mp_int *mp_modpow(mp_int *base, mp_int *exponent, mp_int *modulus)
     mp_free(m_out);
     monty_free(mc);
     return out;
+    } // WINSCP
 }
 
 /*
@@ -1555,6 +1650,7 @@ static void mp_bezout_into(mp_int *a_coeff_out, mp_int *b_coeff_out,
     /* Space to build up the output coefficients, with an extra word
      * so that intermediate values can overflow off the top and still
      * right-shift back down to the correct value */
+    { // WINSCP
     mp_int *ac = mp_make_sized(nw + 1), *bc = mp_make_sized(nw + 1);
 
     /* And a general-purpose temp register */
@@ -1568,8 +1664,9 @@ static void mp_bezout_into(mp_int *a_coeff_out, mp_int *b_coeff_out,
     size_t steps = 3 * nw * BIGNUM_INT_BITS;
     mp_int *record = mp_make_sized(
         (steps*2 + BIGNUM_INT_BITS - 1) / BIGNUM_INT_BITS);
+    size_t step; // WINSCP
 
-    for (size_t step = 0; step < steps; step++) {
+    for (step = 0; step < steps; step++) {
         /*
          * If a and b are both odd, we want to sort them so that a is
          * larger. But if one is even, we want to sort them so that a
@@ -1624,9 +1721,10 @@ static void mp_bezout_into(mp_int *a_coeff_out, mp_int *b_coeff_out,
      * Initially, the result is +1 if a was the nonzero value after
      * reduction, and -1 if b was.
      */
+    { // WINSCP
     unsigned minus_one = b->w[0];
 
-    for (size_t step = steps; step-- > 0 ;) {
+    for (step = steps; step-- > 0 ;) {
         /*
          * Recover the data from the step we're unwinding.
          */
@@ -1702,6 +1800,8 @@ static void mp_bezout_into(mp_int *a_coeff_out, mp_int *b_coeff_out,
     mp_free(bc);
     mp_free(tmp);
     mp_free(record);
+    } // WINSCP
+    } // WINSCP
 }
 
 mp_int *mp_invert(mp_int *x, mp_int *m)
@@ -1751,7 +1851,7 @@ static uint32_t recip_approx_32(uint32_t x)
 
 void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
 {
-    assert(!mp_eq_integer(d, 0));
+    pinitassert(!mp_eq_integer(d, 0));
 
     /*
      * We do division by using Newton-Raphson iteration to converge to
@@ -1833,8 +1933,10 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
      * Make a shifted combination of those two words which puts the
      * topmost bit of the number at bit 63.
      */
+    { // WINSCP
     size_t shift_up = 0;
-    for (size_t i = BIGNUM_INT_BITS_BITS; i-- > 0;) {
+    size_t i; // WINSCP
+    for (i = BIGNUM_INT_BITS_BITS; i-- > 0;) {
         size_t sl = 1 << i;               /* left shift count */
         size_t sr = BIGNUM_INT_BITS - sl; /* complementary right-shift count */
 
@@ -1872,7 +1974,7 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
      * smaller-word shift instructions, e.g. by splitting up into
      * cases.
      */
-    for (size_t i = BIGNUM_INT_BITS_BITS; i-- > 0;) {
+    for (i = BIGNUM_INT_BITS_BITS; i-- > 0;) {
         size_t sl = 1 << i;               /* left shift count */
         size_t sr = BIGNUM_INT_BITS - sl; /* complementary right-shift count */
 
@@ -1895,6 +1997,7 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
      * 191, plus a multiple of BIGNUM_INT_BITS large enough to allow R
      * to hold the combined sizes of n and d.
      */
+    { // WINSCP
     size_t log2_R;
     {
         size_t max_log2_n = (n->nw + d->nw) * BIGNUM_INT_BITS;
@@ -1906,6 +2009,7 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
 
     /* Number of words in a bignum capable of holding numbers the size
      * of twice R. */
+    { // WINSCP
     size_t rw = ((log2_R+2) + BIGNUM_INT_BITS - 1) / BIGNUM_INT_BITS;
 
     /*
@@ -1926,6 +2030,7 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
         /* If we've done all that right, it should be a whole number
          * of words. */
         assert(output_bit_index % BIGNUM_INT_BITS == 0);
+        { // WINSCP
         size_t output_word_index = output_bit_index / BIGNUM_INT_BITS;
 
         mp_add_integer_into_shifted_by_words(
@@ -1933,11 +2038,13 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
         mp_add_integer_into_shifted_by_words(
             r_approx, r_approx, hibits,
             output_word_index + 64 / BIGNUM_INT_BITS);
+        } // WINSCP
     }
 
     /*
      * Make the constant 2*R, which we'll need in the iteration.
      */
+    { // WINSCP
     mp_int *two_R = mp_make_sized(rw);
     mp_add_integer_into_shifted_by_words(
         two_R, two_R, (BignumInt)1 << ((log2_R+1) % BIGNUM_INT_BITS),
@@ -1946,6 +2053,7 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
     /*
      * Scratch space.
      */
+    { // WINSCP
     mp_int *dr = mp_make_sized(rw + d->nw);
     mp_int *diff = mp_make_sized(size_t_max(rw, dr->nw));
     mp_int *product = mp_make_sized(rw + diff->nw);
@@ -1996,6 +2104,7 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
      * Now we've got our reciprocal, we can compute the quotient, by
      * multiplying in n and then shifting down by log2_R bits.
      */
+    { // WINSCP
     mp_int *quotient_full = mp_mul(r_approx, n);
     mp_int quotient_alias = mp_make_alias(
         quotient_full, log2_R / BIGNUM_INT_BITS, quotient_full->nw);
@@ -2005,6 +2114,7 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
     /*
      * Next, compute the remainder.
      */
+    { // WINSCP
     mp_int *remainder = mp_make_sized(d->nw);
     mp_mul_into(remainder, quotient, d);
     mp_sub_into(remainder, n, remainder);
@@ -2014,8 +2124,10 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
      * rounding error. (I _think_ one should be enough, but this
      * routine isn't time-critical enough to take chances.)
      */
+    { // WINSCP
     unsigned q_correction = 0;
-    for (unsigned iter = 0; iter < 2; iter++) {
+    unsigned iter; // WINSCP
+    for (iter = 0; iter < 2; iter++) {
         unsigned need_correction = mp_cmp_hs(remainder, d);
         mp_cond_sub_into(remainder, remainder, d, need_correction);
         q_correction += need_correction;
@@ -2037,6 +2149,14 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
     mp_free(quotient_full);
     mp_free(quotient);
     mp_free(remainder);
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 mp_int *mp_div(mp_int *n, mp_int *d)
@@ -2073,13 +2193,17 @@ mp_int *mp_modsub(mp_int *x, mp_int *y, mp_int *modulus)
 {
     mp_int *diff = mp_make_sized(size_t_max(x->nw, y->nw));
     mp_sub_into(diff, x, y);
+    { // WINSCP
     unsigned negate = mp_cmp_hs(y, x);
     mp_cond_negate(diff, diff, negate);
+    { // WINSCP
     mp_int *reduced = mp_mod(diff, modulus);
     mp_cond_negate(reduced, reduced, negate);
     mp_cond_add_into(reduced, reduced, modulus, negate);
     mp_free(diff);
     return reduced;
+    } // WINSCP
+    } // WINSCP
 }
 
 static mp_int *mp_modadd_in_range(mp_int *x, mp_int *y, mp_int *modulus)
@@ -2192,9 +2316,11 @@ mp_int *mp_modsqrt(ModsqrtContext *sc, mp_int *x, unsigned *success)
     mp_int *mx = monty_import(sc->mc, x);
     mp_int *mroot = monty_modsqrt(sc, mx, success);
     mp_free(mx);
+    { // WINSCP
     mp_int *root = monty_export(sc->mc, mroot);
     mp_free(mroot);
     return root;
+    } // WINSCP
 }
 
 /*
@@ -2257,6 +2383,7 @@ mp_int *monty_modsqrt(ModsqrtContext *sc, mp_int *x, unsigned *success)
 {
     modsqrt_lazy_setup(sc);
 
+    { // WINSCP
     mp_int *scratch_to_free = mp_make_sized(3 * sc->mc->rw);
     mp_int scratch = *scratch_to_free;
 
@@ -2273,15 +2400,19 @@ mp_int *monty_modsqrt(ModsqrtContext *sc, mp_int *x, unsigned *success)
     monty_mul_into(sc->mc, toret, toret, x);
     monty_mul_into(sc->mc, &xk, toret, &xk);
 
+    { // WINSCP
     mp_int tmp = mp_alloc_from_scratch(&scratch, sc->mc->rw);
 
     mp_int power_of_zk = mp_alloc_from_scratch(&scratch, sc->mc->rw);
+    size_t i; // WINSCP
     mp_copy_into(&power_of_zk, sc->zk);
 
-    for (size_t i = 0; i < sc->e; i++) {
+    for (i = 0; i < sc->e; i++) {
+        size_t j; // WINSCP
         mp_copy_into(&tmp, &xk);
-        for (size_t j = i+1; j < sc->e; j++)
+        for (j = i+1; j < sc->e; j++)
             monty_mul_into(sc->mc, &tmp, &tmp, &tmp);
+        { // WINSCP
         unsigned eq1 = mp_cmp_eq(&tmp, monty_identity(sc->mc));
 
         if (i == 0) {
@@ -2296,11 +2427,14 @@ mp_int *monty_modsqrt(ModsqrtContext *sc, mp_int *x, unsigned *success)
             monty_mul_into(sc->mc, &tmp, &xk, &power_of_zk);
             mp_select_into(&xk, &tmp, &xk, eq1);
         }
+        } // WINSCP
     }
 
     mp_free(scratch_to_free);
 
     return toret;
+    } // WINSCP
+    } // WINSCP
 }
 
 mp_int *mp_random_bits_fn(size_t bits, int (*gen_byte)(void))
@@ -2308,7 +2442,8 @@ mp_int *mp_random_bits_fn(size_t bits, int (*gen_byte)(void))
     size_t bytes = (bits + 7) / 8;
     size_t words = (bits + BIGNUM_INT_BITS - 1) / BIGNUM_INT_BITS;
     mp_int *x = mp_make_sized(words);
-    for (size_t i = 0; i < bytes; i++) {
+    size_t i; // WINSCP
+    for (i = 0; i < bytes; i++) {
         BignumInt byte = gen_byte();
         unsigned mask = (1 << size_t_min(8, bits-i*8)) - 1;
         x->w[i / BIGNUM_INT_BYTES] |=

+ 3 - 2
source/putty/sshcommon.c

@@ -1041,11 +1041,12 @@ void ssh1_compute_session_id(
     struct RSAKey *hostkey, struct RSAKey *servkey)
 {
     struct MD5Context md5c;
+    size_t i; // WINSCP
 
     MD5Init(&md5c);
-    for (size_t i = (mp_get_nbits(hostkey->modulus) + 7) / 8; i-- ;)
+    for (i = (mp_get_nbits(hostkey->modulus) + 7) / 8; i-- ;)
         put_byte(&md5c, mp_get_byte(hostkey->modulus, i));
-    for (size_t i = (mp_get_nbits(servkey->modulus) + 7) / 8; i-- ;)
+    for (i = (mp_get_nbits(servkey->modulus) + 7) / 8; i-- ;)
         put_byte(&md5c, mp_get_byte(servkey->modulus, i));
     put_data(&md5c, cookie, 8);
     MD5Final(session_id, &md5c);

+ 3 - 1
source/putty/sshdh.c

@@ -154,7 +154,7 @@ bool dh_is_gex(const struct ssh_kex *kex)
 struct dh_ctx *dh_setup_group(const struct ssh_kex *kex)
 {
     const struct dh_extra *extra = (const struct dh_extra *)kex->extra;
-    assert(!extra->gex);
+    pinitassert(!extra->gex);
     struct dh_ctx *ctx = snew(struct dh_ctx);
     extra->construct(ctx);
     dh_init(ctx);
@@ -258,10 +258,12 @@ const char *dh_validate_f(struct dh_ctx *ctx, mp_int *f)
     } else {
         mp_int *pm1 = mp_copy(ctx->p);
         mp_sub_integer_into(pm1, pm1, 1);
+        { // WINSCP
         unsigned cmp = mp_cmp_hs(f, pm1);
         mp_free(pm1);
         if (cmp)
             return "f value received is too large";
+        } // WINSCP
     }
     return NULL;
 }

+ 16 - 0
source/putty/sshdss.c

@@ -118,6 +118,7 @@ static bool dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
     }
 
     /* Now we're sitting on a 40-byte string for sure. */
+    { // WINSCP
     mp_int *r = mp_from_bytes_be(make_ptrlen(sig.ptr, 20));
     mp_int *s = mp_from_bytes_be(make_ptrlen((const char *)sig.ptr + 20, 20));
     if (!r || !s) {
@@ -137,6 +138,7 @@ static bool dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
     /*
      * Step 1. w <- s^-1 mod q.
      */
+    { // WINSCP
     mp_int *w = mp_invert(s, dss->q);
     if (!w) {
         mp_free(r);
@@ -148,6 +150,7 @@ static bool dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
      * Step 2. u1 <- SHA(message) * w mod q.
      */
     SHA_Simple(data.ptr, data.len, hash);
+    { // WINSCP
     mp_int *sha = mp_from_bytes_be(make_ptrlen(hash, 20));
     mp_int *u1 = mp_modmul(sha, w, dss->q);
 
@@ -180,6 +183,9 @@ static bool dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
     mp_free(v);
     mp_free(r);
     mp_free(s);
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 
     return toret;
 }
@@ -404,8 +410,10 @@ mp_int *dss_gen_k(const char *id_string, mp_int *modulus,
      * Now convert the result into a bignum, and coerce it to the
      * range [2,q), which we do by reducing it mod q-2 and adding 2.
      */
+    { // WINSCP
     mp_int *modminus2 = mp_copy(modulus);
     mp_sub_integer_into(modminus2, modminus2, 2);
+    { // WINSCP
     mp_int *proto_k = mp_from_bytes_be(make_ptrlen(digest512, 64));
     mp_int *k = mp_mod(proto_k, modminus2);
     mp_free(proto_k);
@@ -416,6 +424,8 @@ mp_int *dss_gen_k(const char *id_string, mp_int *modulus,
     smemclr(digest512, sizeof(digest512));
 
     return k;
+    } // WINSCP
+    } // WINSCP
 }
 
 static void dss_sign(ssh_key *key, const void *data, int datalen,
@@ -427,6 +437,7 @@ static void dss_sign(ssh_key *key, const void *data, int datalen,
 
     SHA_Simple(data, datalen, digest);
 
+    { // WINSCP
     mp_int *k = dss_gen_k("DSA deterministic k generator", dss->q, dss->x,
                           digest, sizeof(digest));
     mp_int *kinv = mp_invert(k, dss->q);       /* k^-1 mod q */
@@ -438,9 +449,11 @@ static void dss_sign(ssh_key *key, const void *data, int datalen,
     mp_int *r = mp_mod(gkp, dss->q);        /* r = (g^k mod p) mod q */
     mp_free(gkp);
 
+    { // WINSCP
     mp_int *hash = mp_from_bytes_be(make_ptrlen(digest, 20));
     mp_int *hxr = mp_mul(dss->x, r);
     mp_add_into(hxr, hxr, hash);         /* hash + x*r */
+    { // WINSCP
     mp_int *s = mp_modmul(kinv, hxr, dss->q); /* s = k^-1 * (hash+x*r) mod q */
     mp_free(hxr);
     mp_free(kinv);
@@ -455,6 +468,9 @@ static void dss_sign(ssh_key *key, const void *data, int datalen,
         put_byte(bs, mp_get_byte(s, 19 - i));
     mp_free(r);
     mp_free(s);
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 const ssh_keyalg ssh_dss = {

+ 167 - 43
source/putty/sshecc.c

@@ -42,39 +42,28 @@
 #ifdef MPEXT
 int ec_curve_cleanup = 0;
 
-static void finalize_ec_point(struct ec_point *point)
+static void finalize_common(struct ec_curve * curve)
 {
-    if (point->x != NULL) freebn(point->x);
-    if (point->y != NULL) freebn(point->y);
-    if (point->z != NULL) freebn(point->z);
+    mp_free(curve->p);
 }
 
 static void finalize_wcurve(struct ec_curve *curve)
 {
-    if (curve->p != NULL) freebn(curve->p);
-
-    if (curve->w.a != NULL) freebn(curve->w.a);
-    if (curve->w.b != NULL) freebn(curve->w.b);
-    if (curve->w.n != NULL) freebn(curve->w.n);
-    finalize_ec_point(&curve->w.G);
+    // TODO
+    finalize_common(curve);
 }
 
 static void finalize_mcurve(struct ec_curve *curve)
 {
-    if (curve->p != NULL) freebn(curve->p);
-
-    if (curve->m.a != NULL) freebn(curve->m.a);
-    if (curve->m.b != NULL) freebn(curve->m.b);
-    finalize_ec_point(&curve->m.G);
+    ecc_montgomery_curve_free(curve->m.mc);
+    ecc_montgomery_point_free(curve->m.G);
+    finalize_common(curve);
 }
 
 static void finalize_ecurve(struct ec_curve *curve)
 {
-    if (curve->p != NULL) freebn(curve->p);
-
-    if (curve->e.l != NULL) freebn(curve->e.l);
-    if (curve->e.d != NULL) freebn(curve->e.d);
-    finalize_ec_point(&curve->e.B);
+    // TODO
+    finalize_common(curve);
 }
 #endif
 
@@ -350,7 +339,7 @@ WeierstrassPoint *ecdsa_public(mp_int *private_key, const ssh_keyalg *alg)
     const struct ecsign_extra *extra =
         (const struct ecsign_extra *)alg->extra;
     struct ec_curve *curve = extra->curve();
-    assert(curve->type == EC_WEIERSTRASS);
+    pinitassert(curve->type == EC_WEIERSTRASS);
 
     mp_int *priv_reduced = mp_mod(private_key, curve->p);
     WeierstrassPoint *toret = ecc_weierstrass_multiply(
@@ -365,7 +354,7 @@ static mp_int *eddsa_exponent_from_hash(
     /*
      * Make an integer out of the hash data, little-endian.
      */
-    assert(hash.len >= curve->fieldBytes);
+    pinitassert(hash.len >= curve->fieldBytes);
     mp_int *e = mp_from_bytes_le(make_ptrlen(hash.ptr, curve->fieldBytes));
 
     /*
@@ -378,8 +367,11 @@ static mp_int *eddsa_exponent_from_hash(
     /*
      * Clear exactly three low bits.
      */
-    for (size_t bit = 0; bit < 3; bit++)
+    { // WINSCP
+    size_t bit; // WINSCP
+    for (bit = 0; bit < 3; bit++)
         mp_set_bit(e, bit, 0);
+    } // WINSCP
 
     return e;
 }
@@ -389,22 +381,28 @@ EdwardsPoint *eddsa_public(mp_int *private_key, const ssh_keyalg *alg)
     const struct ecsign_extra *extra =
         (const struct ecsign_extra *)alg->extra;
     struct ec_curve *curve = extra->curve();
-    assert(curve->type == EC_EDWARDS);
+    pinitassert(curve->type == EC_EDWARDS);
 
     ssh_hash *h = ssh_hash_new(extra->hash);
-    for (size_t i = 0; i < curve->fieldBytes; ++i)
+    size_t i; // WINSCP
+    for (i = 0; i < curve->fieldBytes; ++i)
         put_byte(h, mp_get_byte(private_key, i));
 
-    unsigned char hash[extra->hash->hlen];
+    { // WINSCP
+    unsigned char * hash = snewn(extra->hash->hlen, unsigned char); // WINSCP
     ssh_hash_final(h, hash);
 
+    { // WINSCP
     mp_int *exponent = eddsa_exponent_from_hash(
         make_ptrlen(hash, extra->hash->hlen), curve);
 
     EdwardsPoint *toret = ecc_edwards_multiply(curve->e.G, exponent);
     mp_free(exponent);
+    sfree(hash); // WINSCP
 
     return toret;
+    } // WINSCP
+    } // WINSCP
 }
 
 /* ----------------------------------------------------------------------
@@ -422,8 +420,11 @@ static void BinarySink_put_mp_le_unsigned(BinarySink *bs, mp_int *x)
     size_t bytes = (mp_get_nbits(x) + 7) / 8;
 
     put_uint32(bs, bytes);
-    for (size_t i = 0; i < bytes; ++i)
+    { // WINSCP
+    size_t i; // WINSCP
+    for (i = 0; i < bytes; ++i)
         put_byte(bs, mp_get_byte(x, i));
+    } // WINSCP
 }
 #define put_mp_le_unsigned(bs, x) \
     BinarySink_put_mp_le_unsigned(BinarySink_UPCAST(bs), x)
@@ -431,10 +432,11 @@ static void BinarySink_put_mp_le_unsigned(BinarySink *bs, mp_int *x)
 static WeierstrassPoint *ecdsa_decode(
     ptrlen encoded, const struct ec_curve *curve)
 {
-    assert(curve->type == EC_WEIERSTRASS);
+    pinitassert(curve->type == EC_WEIERSTRASS);
     BinarySource src[1];
 
     BinarySource_BARE_INIT(src, encoded.ptr, encoded.len);
+    { // WINSCP
     unsigned char format_type = get_byte(src);
 
     WeierstrassPoint *P;
@@ -484,6 +486,7 @@ static WeierstrassPoint *ecdsa_decode(
     }
 
     return P;
+    } // WINSCP
 }
 
 static WeierstrassPoint *BinarySource_get_wpoint(
@@ -527,10 +530,13 @@ static void BinarySink_put_wpoint(
          * For ECDSA, we only ever output uncompressed points.
          */
         put_byte(bs_inner, 0x04);
-        for (size_t i = curve->fieldBytes; i--;)
+        { // WINSCP
+        size_t i; // WINSCP
+        for (i = curve->fieldBytes; i--;)
             put_byte(bs_inner, mp_get_byte(x, i));
-        for (size_t i = curve->fieldBytes; i--;)
+        for (i = curve->fieldBytes; i--;)
             put_byte(bs_inner, mp_get_byte(y, i));
+        } // WINSCP
 
         mp_free(x);
         mp_free(y);
@@ -547,6 +553,7 @@ static EdwardsPoint *eddsa_decode(ptrlen encoded, const struct ec_curve *curve)
     assert(curve->type == EC_EDWARDS);
     assert(curve->fieldBits % 8 == 7);
 
+    { // WINSCP
     mp_int *y = mp_from_bytes_le(encoded);
 
     if (mp_get_nbits(y) > curve->fieldBits+1) {
@@ -556,9 +563,11 @@ static EdwardsPoint *eddsa_decode(ptrlen encoded, const struct ec_curve *curve)
 
     /* The topmost bit of the encoding isn't part of y, so it stores
      * the bottom bit of x. Extract it, and zero that bit in y. */
+    { // WINSCP
     unsigned desired_x_parity = mp_get_bit(y, curve->fieldBits);
     mp_set_bit(y, curve->fieldBits, 0);
 
+    { // WINSCP
     EdwardsPoint *P = ecc_edwards_point_new_from_y(
         curve->e.ec, y, desired_x_parity);
     mp_free(y);
@@ -567,6 +576,9 @@ static EdwardsPoint *eddsa_decode(ptrlen encoded, const struct ec_curve *curve)
      * equation, unless ecc.c wasn't able to construct one at all, in
      * which case P is now NULL. Either way, return it. */
     return P;
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 static EdwardsPoint *BinarySource_get_epoint(
@@ -596,8 +608,11 @@ static void BinarySink_put_epoint(
      */
     if (!bare)
         put_uint32(bs, curve->fieldBytes);   /* string length field */
-    for (size_t i = 0; i < curve->fieldBytes - 1; i++)
+    { // WINSCP
+    size_t i; // WINSCP
+    for (i = 0; i < curve->fieldBytes - 1; i++)
         put_byte(bs, mp_get_byte(y, i));
+    } // WINSCP
     put_byte(bs, (mp_get_byte(y, curve->fieldBytes - 1) & 0x7F) |
              (mp_get_bit(x, 0) << 7));
 
@@ -638,7 +653,7 @@ static ssh_key *ecdsa_new_pub(const ssh_keyalg *alg, ptrlen data)
     const struct ecsign_extra *extra =
         (const struct ecsign_extra *)alg->extra;
     struct ec_curve *curve = extra->curve();
-    assert(curve->type == EC_WEIERSTRASS);
+    pinitassert(curve->type == EC_WEIERSTRASS);
 
     BinarySource src[1];
     BinarySource_BARE_INIT(src, data.ptr, data.len);
@@ -648,6 +663,7 @@ static ssh_key *ecdsa_new_pub(const ssh_keyalg *alg, ptrlen data)
     if (!ptrlen_eq_string(get_string(src), curve->name))
         return NULL;
 
+    { // WINSCP
     struct ecdsa_key *ek = snew(struct ecdsa_key);
     ek->sshk.vt = alg;
     ek->curve = curve;
@@ -661,6 +677,7 @@ static ssh_key *ecdsa_new_pub(const ssh_keyalg *alg, ptrlen data)
     ek->privateKey = NULL;
 
     return &ek->sshk;
+    } // WINSCP
 }
 
 static ssh_key *eddsa_new_pub(const ssh_keyalg *alg, ptrlen data)
@@ -668,12 +685,13 @@ static ssh_key *eddsa_new_pub(const ssh_keyalg *alg, ptrlen data)
     const struct ecsign_extra *extra =
         (const struct ecsign_extra *)alg->extra;
     struct ec_curve *curve = extra->curve();
-    assert(curve->type == EC_EDWARDS);
+    pinitassert(curve->type == EC_EDWARDS);
 
     BinarySource src[1];
     BinarySource_BARE_INIT(src, data.ptr, data.len);
     get_string(src);
 
+    { // WINSCP
     struct eddsa_key *ek = snew(struct eddsa_key);
     ek->sshk.vt = alg;
     ek->curve = curve;
@@ -686,6 +704,7 @@ static ssh_key *eddsa_new_pub(const ssh_keyalg *alg, ptrlen data)
     }
 
     return &ek->sshk;
+    } // WINSCP
 }
 
 static char *ecc_cache_str_shared(
@@ -696,11 +715,13 @@ static char *ecc_cache_str_shared(
     if (curve_name)
         strbuf_catf(sb, "%s,", curve_name);
 
+    { // WINSCP
     char *hx = mp_get_hex(x);
     char *hy = mp_get_hex(y);
     strbuf_catf(sb, "0x%s,0x%s", hx, hy);
     sfree(hx);
     sfree(hy);
+    } // WINSCP
 
     return strbuf_to_str(sb);
 }
@@ -711,10 +732,12 @@ static char *ecdsa_cache_str(ssh_key *key)
     mp_int *x, *y;
 
     ecc_weierstrass_get_affine(ek->publicKey, &x, &y);
+    { // WINSCP
     char *toret = ecc_cache_str_shared(ek->curve->name, x, y);
     mp_free(x);
     mp_free(y);
     return toret;
+    } // WINSCP
 }
 
 static char *eddsa_cache_str(ssh_key *key)
@@ -723,10 +746,12 @@ static char *eddsa_cache_str(ssh_key *key)
     mp_int *x, *y;
 
     ecc_edwards_get_affine(ek->publicKey, &x, &y);
+    { // WINSCP
     char *toret = ecc_cache_str_shared(ek->curve->name, x, y);
     mp_free(x);
     mp_free(y);
     return toret;
+    } // WINSCP
 }
 
 static void ecdsa_public_blob(ssh_key *key, BinarySink *bs)
@@ -769,6 +794,7 @@ static ssh_key *ecdsa_new_priv(const ssh_keyalg *alg, ptrlen pub, ptrlen priv)
     ssh_key *sshk = ecdsa_new_pub(alg, pub);
     if (!sshk)
         return NULL;
+    { // WINSCP
     struct ecdsa_key *ek = container_of(sshk, struct ecdsa_key, sshk);
 
     BinarySource src[1];
@@ -776,6 +802,7 @@ static ssh_key *ecdsa_new_priv(const ssh_keyalg *alg, ptrlen pub, ptrlen priv)
     ek->privateKey = get_mp_ssh2(src);
 
     return &ek->sshk;
+    } // WINSCP
 }
 
 static ssh_key *eddsa_new_priv(const ssh_keyalg *alg, ptrlen pub, ptrlen priv)
@@ -783,6 +810,7 @@ static ssh_key *eddsa_new_priv(const ssh_keyalg *alg, ptrlen pub, ptrlen priv)
     ssh_key *sshk = eddsa_new_pub(alg, pub);
     if (!sshk)
         return NULL;
+    { // WINSCP
     struct eddsa_key *ek = container_of(sshk, struct eddsa_key, sshk);
 
     BinarySource src[1];
@@ -790,6 +818,7 @@ static ssh_key *eddsa_new_priv(const ssh_keyalg *alg, ptrlen pub, ptrlen priv)
     ek->privateKey = get_mp_le(src);
 
     return &ek->sshk;
+    } // WINSCP
 }
 
 static ssh_key *eddsa_new_priv_openssh(
@@ -800,6 +829,7 @@ static ssh_key *eddsa_new_priv_openssh(
     struct ec_curve *curve = extra->curve();
     assert(curve->type == EC_EDWARDS);
 
+    { // WINSCP
     ptrlen pubkey_pl = get_string(src);
     ptrlen privkey_extended_pl = get_string(src);
     if (get_err(src) || pubkey_pl.len != curve->fieldBytes)
@@ -813,9 +843,11 @@ static ssh_key *eddsa_new_priv_openssh(
      * won't behave identically to the way OpenSSH would have treated
      * it.
      */
+    { // WINSCP
     BinarySource subsrc[1];
     BinarySource_BARE_INIT(
         subsrc, privkey_extended_pl.ptr, privkey_extended_pl.len);
+    { // WINSCP
     ptrlen privkey_pl = get_data(subsrc, curve->fieldBytes);
     ptrlen pubkey_copy_pl = get_data(subsrc, curve->fieldBytes);
     if (get_err(subsrc) || get_avail(subsrc))
@@ -823,6 +855,7 @@ static ssh_key *eddsa_new_priv_openssh(
     if (!ptrlen_eq_ptrlen(pubkey_pl, pubkey_copy_pl))
         return NULL;
 
+    { // WINSCP
     struct eddsa_key *ek = snew(struct eddsa_key);
     ek->sshk.vt = alg;
     ek->curve = curve;
@@ -836,6 +869,10 @@ static ssh_key *eddsa_new_priv_openssh(
     ek->privateKey = mp_from_bytes_le(privkey_pl);
 
     return &ek->sshk;
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 static void eddsa_openssh_blob(ssh_key *key, BinarySink *bs)
@@ -844,12 +881,15 @@ static void eddsa_openssh_blob(ssh_key *key, BinarySink *bs)
     assert(ek->curve->type == EC_EDWARDS);
 
     /* Encode the public and private points as strings */
+    { // WINSCP
     strbuf *pub_sb = strbuf_new();
     put_epoint(pub_sb, ek->publicKey, ek->curve, false);
+    { // WINSCP
     ptrlen pub = make_ptrlen(pub_sb->s + 4, pub_sb->len - 4);
 
     strbuf *priv_sb = strbuf_new();
     put_mp_le_unsigned(priv_sb, ek->privateKey);
+    { // WINSCP
     ptrlen priv = make_ptrlen(priv_sb->s + 4, priv_sb->len - 4);
 
     put_stringpl(bs, pub);
@@ -862,6 +902,9 @@ static void eddsa_openssh_blob(ssh_key *key, BinarySink *bs)
 
     strbuf_free(pub_sb);
     strbuf_free(priv_sb);
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 static ssh_key *ecdsa_new_priv_openssh(
@@ -874,6 +917,7 @@ static ssh_key *ecdsa_new_priv_openssh(
 
     get_string(src);
 
+    { // WINSCP
     struct eddsa_key *ek = snew(struct eddsa_key);
     ek->sshk.vt = alg;
     ek->curve = curve;
@@ -887,6 +931,7 @@ static ssh_key *ecdsa_new_priv_openssh(
     ek->privateKey = get_mp_ssh2(src);
 
     return &ek->sshk;
+    } // WINSCP
 }
 
 static void ecdsa_openssh_blob(ssh_key *key, BinarySink *bs)
@@ -910,26 +955,31 @@ static mp_int *ecdsa_signing_exponent_from_data(
     ptrlen data)
 {
     /* Hash the data being signed. */
-    unsigned char hash[extra->hash->hlen];
+    unsigned char * hash = snewn(extra->hash->hlen, unsigned char); // WINSCP
     ssh_hash *h = ssh_hash_new(extra->hash);
     put_data(h, data.ptr, data.len);
     ssh_hash_final(h, hash);
+    sfree(hash);
 
     /*
      * Take the leftmost b bits of the hash of the signed data (where
      * b is the number of bits in order(G)), interpreted big-endian.
      */
+    { // WINSCP
     mp_int *z = mp_from_bytes_be(make_ptrlen(hash, extra->hash->hlen));
     size_t zbits = mp_get_nbits(z);
     size_t nbits = mp_get_nbits(curve->w.G_order);
     size_t shift = zbits - nbits;
     /* Bound the shift count below at 0, using bit twiddling to avoid
      * a conditional branch */
-    shift &= ~-(shift >> (CHAR_BIT * sizeof(size_t) - 1));
+    shift &= ~-(int)(shift >> (CHAR_BIT * sizeof(size_t) - 1)); // WINSCP
+    { // WINSCP
     mp_int *toret = mp_rshift_safe(z, shift);
     mp_free(z);
 
     return toret;
+    } // WINSCP
+    } // WINSCP
 }
 
 static bool ecdsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
@@ -946,12 +996,14 @@ static bool ecdsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
         return false;
 
     /* Everything else is nested inside a sub-string. Descend into that. */
+    { // WINSCP
     ptrlen sigstr = get_string(src);
     if (get_err(src))
         return false;
     BinarySource_BARE_INIT(src, sigstr.ptr, sigstr.len);
 
     /* Extract the signature integers r,s */
+    { // WINSCP
     mp_int *r = get_mp_ssh2(src);
     mp_int *s = get_mp_ssh2(src);
     if (get_err(src)) {
@@ -961,6 +1013,7 @@ static bool ecdsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
     }
 
     /* Basic sanity checks: 0 < r,s < order(G) */
+    { // WINSCP
     unsigned invalid = 0;
     invalid |= mp_eq_integer(r, 0);
     invalid |= mp_eq_integer(s, 0);
@@ -968,22 +1021,28 @@ static bool ecdsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
     invalid |= mp_cmp_hs(s, ek->curve->w.G_order);
 
     /* Get the hash of the signed data, converted to an integer */
+    { // WINSCP
     mp_int *z = ecdsa_signing_exponent_from_data(ek->curve, extra, data);
 
     /* Verify the signature integers against the hash */
     mp_int *w = mp_invert(s, ek->curve->w.G_order);
     mp_int *u1 = mp_modmul(z, w, ek->curve->w.G_order);
     mp_free(z);
+    { // WINSCP
     mp_int *u2 = mp_modmul(r, w, ek->curve->w.G_order);
     mp_free(w);
+    { // WINSCP
     WeierstrassPoint *u1G = ecc_weierstrass_multiply(ek->curve->w.G, u1);
     mp_free(u1);
+    { // WINSCP
     WeierstrassPoint *u2P = ecc_weierstrass_multiply(ek->publicKey, u2);
     mp_free(u2);
+    { // WINSCP
     WeierstrassPoint *sum = ecc_weierstrass_add_general(u1G, u2P);
     ecc_weierstrass_point_free(u1G);
     ecc_weierstrass_point_free(u2P);
 
+    { // WINSCP
     mp_int *x;
     ecc_weierstrass_get_affine(sum, &x, NULL);
     ecc_weierstrass_point_free(sum);
@@ -996,6 +1055,15 @@ static bool ecdsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
     mp_free(s);
 
     return !invalid;
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 static mp_int *eddsa_signing_exponent_from_data(
@@ -1003,18 +1071,21 @@ static mp_int *eddsa_signing_exponent_from_data(
     ptrlen r_encoded, ptrlen data)
 {
     /* Hash (r || public key || message) */
-    unsigned char hash[extra->hash->hlen];
+    unsigned char * hash = snewn(extra->hash->hlen, unsigned char);
     ssh_hash *h = ssh_hash_new(extra->hash);
     put_data(h, r_encoded.ptr, r_encoded.len);
     put_epoint(h, ek->publicKey, ek->curve, true); /* omit string header */
     put_data(h, data.ptr, data.len);
     ssh_hash_final(h, hash);
+    sfree(hash);
 
     /* Convert to an integer */
+    { // WINSCP
     mp_int *toret = mp_from_bytes_le(make_ptrlen(hash, extra->hash->hlen));
 
     smemclr(hash, extra->hash->hlen);
     return toret;
+    } // WINSCP
 }
 
 static bool eddsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
@@ -1032,18 +1103,22 @@ static bool eddsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
 
     /* Now expect a single string which is the concatenation of an
      * encoded curve point r and an integer s. */
+    { // WINSCP
     ptrlen sigstr = get_string(src);
     if (get_err(src))
         return false;
     BinarySource_BARE_INIT(src, sigstr.ptr, sigstr.len);
+    { // WINSCP
     ptrlen rstr = get_data(src, ek->curve->fieldBytes);
     ptrlen sstr = get_data(src, ek->curve->fieldBytes);
     if (get_err(src) || get_avail(src))
         return false;
 
+    { // WINSCP
     EdwardsPoint *r = eddsa_decode(rstr, ek->curve);
     if (!r)
         return false;
+    { // WINSCP
     mp_int *s = mp_from_bytes_le(sstr);
 
     mp_int *H = eddsa_signing_exponent_from_data(ek, extra, rstr, data);
@@ -1051,16 +1126,26 @@ static bool eddsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
     /* Verify that s*G == r + H*publicKey */
     EdwardsPoint *lhs = ecc_edwards_multiply(ek->curve->e.G, s);
     mp_free(s);
+    { // WINSCP
     EdwardsPoint *hpk = ecc_edwards_multiply(ek->publicKey, H);
     mp_free(H);
+    { // WINSCP
     EdwardsPoint *rhs = ecc_edwards_add(r, hpk);
     ecc_edwards_point_free(hpk);
+    { // WINSCP
     unsigned valid = ecc_edwards_eq(lhs, rhs);
     ecc_edwards_point_free(lhs);
     ecc_edwards_point_free(rhs);
     ecc_edwards_point_free(r);
 
     return valid;
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 static void ecdsa_sign(ssh_key *key, const void *data, int datalen,
@@ -1071,6 +1156,7 @@ static void ecdsa_sign(ssh_key *key, const void *data, int datalen,
         (const struct ecsign_extra *)ek->sshk.vt->extra;
     assert(ek->privateKey);
 
+    { // WINSCP
     mp_int *z = ecdsa_signing_exponent_from_data(
         ek->curve, extra, make_ptrlen(data, datalen));
 
@@ -1085,22 +1171,27 @@ static void ecdsa_sign(ssh_key *key, const void *data, int datalen,
             ek->privateKey, digest, sizeof(digest));
     }
 
+    { // WINSCP
     WeierstrassPoint *kG = ecc_weierstrass_multiply(ek->curve->w.G, k);
     mp_int *x;
     ecc_weierstrass_get_affine(kG, &x, NULL);
     ecc_weierstrass_point_free(kG);
 
     /* r = kG.x mod order(G) */
+    { // WINSCP
     mp_int *r = mp_mod(x, ek->curve->w.G_order);
     mp_free(x);
 
     /* s = (z + r * priv)/k mod n */
+    { // WINSCP
     mp_int *rPriv = mp_modmul(r, ek->privateKey, ek->curve->w.G_order);
     mp_int *numerator = mp_modadd(z, rPriv, ek->curve->w.G_order);
     mp_free(z);
     mp_free(rPriv);
+    { // WINSCP
     mp_int *kInv = mp_invert(k, ek->curve->w.G_order);
     mp_free(k);
+    { // WINSCP
     mp_int *s = mp_modmul(numerator, kInv, ek->curve->w.G_order);
     mp_free(numerator);
     mp_free(kInv);
@@ -1108,13 +1199,21 @@ static void ecdsa_sign(ssh_key *key, const void *data, int datalen,
     /* Format the output */
     put_stringz(bs, ek->sshk.vt->ssh_id);
 
+    { // WINSCP
     strbuf *substr = strbuf_new();
     put_mp_ssh2(substr, r);
     put_mp_ssh2(substr, s);
     put_stringsb(bs, substr);
+    } // WINSCP
 
     mp_free(r);
     mp_free(s);
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 static void eddsa_sign(ssh_key *key, const void *data, int datalen,
@@ -1139,16 +1238,20 @@ static void eddsa_sign(ssh_key *key, const void *data, int datalen,
      * First, we hash the private key integer (bare, little-endian)
      * into a hash generating 2*fieldBytes of output.
      */
-    unsigned char hash[extra->hash->hlen];
+    { // WINSCP
+    unsigned char * hash = snewn(extra->hash->hlen, unsigned char); // WINSCP
     ssh_hash *h = ssh_hash_new(extra->hash);
-    for (size_t i = 0; i < ek->curve->fieldBytes; ++i)
+    size_t i; // WINSCP
+    for (i = 0; i < ek->curve->fieldBytes; ++i)
         put_byte(h, mp_get_byte(ek->privateKey, i));
     ssh_hash_final(h, hash);
+    sfree(hash); // WINSCP
 
     /*
      * The first half of the output hash is converted into an
      * integer a, by the standard EdDSA transformation.
      */
+    { // WINSCP
     mp_int *a = eddsa_exponent_from_hash(
         make_ptrlen(hash, ek->curve->fieldBytes), ek->curve);
 
@@ -1162,10 +1265,12 @@ static void eddsa_sign(ssh_key *key, const void *data, int datalen,
              extra->hash->hlen - ek->curve->fieldBytes);
     put_data(h, data, datalen);
     ssh_hash_final(h, hash);
+    { // WINSCP
     mp_int *log_r_unreduced = mp_from_bytes_le(
         make_ptrlen(hash, extra->hash->hlen));
     mp_int *log_r = mp_mod(log_r_unreduced, ek->curve->e.G_order);
     mp_free(log_r_unreduced);
+    { // WINSCP
     EdwardsPoint *r = ecc_edwards_multiply(ek->curve->e.G, log_r);
 
     /*
@@ -1180,6 +1285,7 @@ static void eddsa_sign(ssh_key *key, const void *data, int datalen,
      * Compute the hash of (r || public key || message) just as
      * eddsa_verify does.
      */
+    { // WINSCP
     mp_int *H = eddsa_signing_exponent_from_data(
         ek, extra, ptrlen_from_strbuf(r_enc), make_ptrlen(data, datalen));
 
@@ -1196,9 +1302,17 @@ static void eddsa_sign(ssh_key *key, const void *data, int datalen,
     put_uint32(bs, r_enc->len + ek->curve->fieldBytes);
     put_data(bs, r_enc->u, r_enc->len);
     strbuf_free(r_enc);
-    for (size_t i = 0; i < ek->curve->fieldBytes; ++i)
+    { // WINSCP
+    size_t i;
+    for (i = 0; i < ek->curve->fieldBytes; ++i)
         put_byte(bs, mp_get_byte(s, i));
     mp_free(s);
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
+    } // WINSCP
 }
 
 const struct ecsign_extra sign_extra_ed25519 = {
@@ -1353,8 +1467,9 @@ static void ssh_ecdhkex_w_setup(ecdh_key *dh)
 
 static void ssh_ecdhkex_m_setup(ecdh_key *dh)
 {
-    unsigned char bytes[dh->curve->fieldBytes];
-    for (size_t i = 0; i < sizeof(bytes); ++i)
+    unsigned char * bytes = snewn(dh->curve->fieldBytes, unsigned char); // WINSCP
+    size_t i; // WINSCP
+    for (i = 0; i < sizeof(bytes); ++i)
         bytes[i] = random_byte();
 
     bytes[0] &= 0xF8;
@@ -1362,6 +1477,7 @@ static void ssh_ecdhkex_m_setup(ecdh_key *dh)
     bytes[dh->curve->fieldBytes-1] |= 0x40;
     dh->private = mp_from_bytes_le(make_ptrlen(bytes, dh->curve->fieldBytes));
     smemclr(bytes, sizeof(bytes));
+    sfree(bytes); // WINSCP
 
     dh->m_public = ecc_montgomery_multiply(dh->curve->m.G, dh->private);
 }
@@ -1386,8 +1502,9 @@ static void ssh_ecdhkex_w_getpublic(ecdh_key *dh, BinarySink *bs)
 static void ssh_ecdhkex_m_getpublic(ecdh_key *dh, BinarySink *bs)
 {
     mp_int *x;
+    size_t i; // WINSCP
     ecc_montgomery_get_affine(dh->m_public, &x);
-    for (size_t i = 0; i < dh->curve->fieldBytes; ++i)
+    for (i = 0; i < dh->curve->fieldBytes; ++i)
         put_byte(bs, mp_get_byte(x, i));
     mp_free(x);
 }
@@ -1403,6 +1520,7 @@ static mp_int *ssh_ecdhkex_w_getkey(ecdh_key *dh, ptrlen remoteKey)
     if (!remote_p)
         return NULL;
 
+    { // WINSCP
     WeierstrassPoint *p = ecc_weierstrass_multiply(remote_p, dh->private);
 
     mp_int *x;
@@ -1412,6 +1530,7 @@ static mp_int *ssh_ecdhkex_w_getkey(ecdh_key *dh, ptrlen remoteKey)
     ecc_weierstrass_point_free(p);
 
     return x;
+    } // WINSCP
 }
 
 static mp_int *ssh_ecdhkex_m_getkey(ecdh_key *dh, ptrlen remoteKey)
@@ -1421,6 +1540,7 @@ static mp_int *ssh_ecdhkex_m_getkey(ecdh_key *dh, ptrlen remoteKey)
         dh->curve->m.mc, remote_x);
     mp_free(remote_x);
 
+    { // WINSCP
     MontgomeryPoint *p = ecc_montgomery_multiply(remote_p, dh->private);
     mp_int *x;
     ecc_montgomery_get_affine(p, &x);
@@ -1442,14 +1562,18 @@ static mp_int *ssh_ecdhkex_m_getkey(ecdh_key *dh, ptrlen remoteKey)
      * being zero, so that has to be converted into an SSH-2 bignum
      * with the _low_ byte zero, i.e. a multiple of 256.
      */
+    { // WINSCP
     strbuf *sb = strbuf_new();
-    for (size_t i = 0; i < dh->curve->fieldBytes; ++i)
+    size_t i;
+    for (i = 0; i < dh->curve->fieldBytes; ++i)
         put_byte(sb, mp_get_byte(x, i));
     mp_free(x);
     x = mp_from_bytes_be(ptrlen_from_strbuf(sb));
     strbuf_free(sb);
 
     return x;
+    } // WINSCP
+    } // WINSCP
 }
 
 mp_int *ssh_ecdhkex_getkey(ecdh_key *dh, ptrlen remoteKey)

+ 13 - 3
source/putty/sshrsa.c

@@ -105,12 +105,16 @@ mp_int *crt_modpow(mp_int *base, mp_int *exp, mp_int *mod,
     /*
      * Do the two modpows.
      */
+    { // WINSCP
     mp_int *base_mod_p = mp_mod(base, p);
     presult = mp_modpow(base_mod_p, pexp, p);
     mp_free(base_mod_p);
+    } // WINSCP
+    { // WINSCP
     mp_int *base_mod_q = mp_mod(base, q);
     qresult = mp_modpow(base_mod_q, qexp, q);
     mp_free(base_mod_q);
+    } // WINSCP
 
     /*
      * Recombine the results. We want a value which is congruent to
@@ -124,8 +128,10 @@ mp_int *crt_modpow(mp_int *base, mp_int *exp, mp_int *mod,
      *
      * (If presult-qresult < 0, we add p to it to keep it positive.)
      */
+    { // WINSCP
     unsigned presult_too_small = mp_cmp_hs(qresult, presult);
     mp_cond_add_into(presult, presult, p, presult_too_small);
+    } // WINSCP
 
     diff = mp_sub(presult, qresult);
     multiplier = mp_mul(iqmp, q);
@@ -177,7 +183,8 @@ bool rsa_ssh1_decrypt_pkcs1(mp_int *input, struct RSAKey *key,
 
     {
         mp_int *b = rsa_ssh1_decrypt(input, key);
-        for (size_t i = (mp_get_nbits(key->modulus) + 7) / 8; i-- > 0 ;) {
+        size_t i; // WINSCP
+        for (i = (mp_get_nbits(key->modulus) + 7) / 8; i-- > 0 ;) {
             put_byte(data, mp_get_byte(b, i));
         }
         mp_free(b);
@@ -295,8 +302,10 @@ bool rsa_verify(struct RSAKey *key)
      * should instead flip them round into the canonical order of
      * p > q. This also involves regenerating iqmp.
      */
+    { // WINSCP
     unsigned swap_pq = mp_cmp_hs(key->q, key->p);
     mp_cond_swap(key->p, key->q, swap_pq);
+    } // WINSCP
     mp_free(key->iqmp);
     key->iqmp = mp_invert(key->q, key->p);
 
@@ -631,9 +640,10 @@ static bool rsa2_verify(ssh_key *key, ptrlen sig, ptrlen data)
     out = mp_modpow(in, rsa->exponent, rsa->modulus);
     mp_free(in);
 
-    unsigned diff = 0;
 
     { // WINSCP
+    unsigned diff = 0;
+
     size_t nbytes = (mp_get_nbits(rsa->modulus) + 7) / 8;
     unsigned char *bytes = rsa_pkcs1_signature_string(nbytes, &ssh_sha1, data);
     size_t i; // WINSCP
@@ -641,10 +651,10 @@ static bool rsa2_verify(ssh_key *key, ptrlen sig, ptrlen data)
         diff |= bytes[nbytes-1 - i] ^ mp_get_byte(out, i);
     smemclr(bytes, nbytes);
     sfree(bytes);
-    } // WINSCP
     mp_free(out);
 
     return diff == 0;
+    } // WINSCP
 }
 
 static void rsa2_sign(ssh_key *key, const void *data, int datalen,