Index: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfcrypt/src/integer.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/integer.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfcrypt/src/integer.c	(revision 464)
@@ -272,21 +272,8 @@
 int mp_leading_bit (mp_int * a)
 {
-    int bit = 0;
-    mp_int t;
-
-    if (mp_init_copy(&t, a) != MP_OKAY)
-        return 0;
-
-    while (mp_iszero(&t) == MP_NO) {
-#ifndef MP_8BIT
-        bit = (t.dp[0] & 0x80) != 0;
-#else
-        bit = ((t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80) != 0;
-#endif
-        if (mp_div_2d (&t, 8, &t, NULL) != MP_OKAY)
-            break;
-    }
-    mp_clear(&t);
-    return bit;
+    int c = mp_count_bits(a);
+
+    if (c == 0) return 0;
+    return (c % 8) == 0;
 }
 
@@ -335,7 +322,12 @@
     len = mp_unsigned_bin_size(a);
 
+    if (len > c) {
+      return MP_VAL;
+    }
+
     /* pad front w/ zeros to match length */
-    for (i = 0; i < c - len; i++)
-        b[i] = 0x00;
+    for (i = 0; i < c - len; i++) {
+      b[i] = 0x00;
+    }
     return mp_to_unsigned_bin(a, b + i);
 }
@@ -555,4 +547,12 @@
 }
 
+int mp_cond_swap_ct (mp_int * a, mp_int * b, int c, int m)
+{
+    (void)c;
+    if (m == 1)
+        mp_exch(a, b);
+    return MP_OKAY;
+}
+
 
 /* shift right a certain number of bits */
@@ -563,4 +563,19 @@
     mp_digit D = x;
 
+    /* shifting by a negative number not supported, and shifting by
+     * zero changes nothing.
+     */
+    if (x <= 0) return;
+
+    /* shift digits first if needed */
+    if (x >= DIGIT_BIT) {
+        mp_rshd(c, x / DIGIT_BIT);
+        /* recalculate number of bits to shift */
+        D = x % DIGIT_BIT;
+        /* check if any more shifting needed */
+        if (D == 0) return;
+    }
+
+    /* zero shifted is always zero */
     if (mp_iszero(c)) return;
 
@@ -670,6 +685,8 @@
   }
   /* clear the digit that is not completely outside/inside the modulus */
-  c->dp[b / DIGIT_BIT] &= (mp_digit) ((((mp_digit) 1) <<
-              (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
+  x = DIGIT_BIT - (b % DIGIT_BIT);
+  if (x != DIGIT_BIT) {
+    c->dp[b / DIGIT_BIT] &= ~((mp_digit)0) >> (x + ((sizeof(mp_digit)*8) - DIGIT_BIT));
+  }
   mp_clamp (c);
   return MP_OKAY;
@@ -681,8 +698,16 @@
 {
   int     res;
-
-  /* make sure there are at least two digits */
-  if (a->alloc < 2) {
-     if ((res = mp_grow(a, 2)) != MP_OKAY) {
+  int     digits_needed;
+
+  while (c > 0 && b[0] == 0) {
+      c--;
+      b++;
+  }
+
+  digits_needed = ((c * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT;
+
+  /* make sure there are enough digits available */
+  if (a->alloc < digits_needed) {
+     if ((res = mp_grow(a, digits_needed)) != MP_OKAY) {
         return res;
      }
@@ -700,9 +725,11 @@
 #ifndef MP_8BIT
       a->dp[0] |= *b++;
-      a->used += 1;
+      if (a->used == 0)
+          a->used = 1;
 #else
       a->dp[0] = (*b & MP_MASK);
       a->dp[1] |= ((*b++ >> 7U) & 1);
-      a->used += 2;
+      if (a->used == 0)
+          a->used = 2;
 #endif
   }
@@ -1578,4 +1605,22 @@
   mp_clamp (b);
   return MP_OKAY;
+}
+
+/* c = a / 2 (mod b) - constant time (a < b and positive) */
+int mp_div_2_mod_ct(mp_int *a, mp_int *b, mp_int *c)
+{
+    int res;
+
+    if (mp_isodd(a)) {
+        res = mp_add(a, b, c);
+        if (res == MP_OKAY) {
+            res = mp_div_2(c, c);
+        }
+    }
+    else {
+        res = mp_div_2(a, c);
+    }
+
+    return res;
 }
 
@@ -1991,5 +2036,5 @@
 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
      if (((P->used * 2 + 1) < (int)MP_WARRAY) &&
-          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+          P->used < (1L << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
         redux = fast_mp_montgomery_reduce;
      } else
@@ -2237,15 +2282,17 @@
 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
   if (((P->used * 2 + 1) < (int)MP_WARRAY) &&
-       P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+       P->used < (1L << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
      redux = fast_mp_montgomery_reduce;
   } else
 #endif
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
   {
-#ifdef BN_MP_MONTGOMERY_REDUCE_C
      /* use slower baseline Montgomery method */
      redux = mp_montgomery_reduce;
-#else
-     return MP_VAL;
-#endif
+  }
+#endif
+
+  if (redux == NULL) {
+      return MP_VAL;
   }
 
@@ -2449,4 +2496,6 @@
 #endif
 
+  XMEMSET(W, 0, (n->used * 2 + 1) * sizeof(mp_word));
+
   /* first we have to get the digits of the input into
    * an array of double precision words W[...]
@@ -2465,9 +2514,4 @@
     for (ix = 0; ix < x->used; ix++) {
       *_W++ = *tmpx++;
-    }
-
-    /* zero the high words of W[a->used..m->used*2] */
-    for (; ix < n->used * 2 + 1; ix++) {
-      *_W++ = 0;
     }
   }
@@ -2597,5 +2641,5 @@
   if ((digs < (int)MP_WARRAY) &&
       n->used <
-      (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+      (1L << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
     return fast_mp_montgomery_reduce (x, n, rho);
   }
@@ -2997,4 +3041,30 @@
 }
 
+/* d = a - b (mod c) - a < c and b < c and positive */
+int mp_submod_ct(mp_int* a, mp_int* b, mp_int* c, mp_int* d)
+{
+    int res;
+
+    res = mp_sub(a, b, d);
+    if (res == MP_OKAY && mp_isneg(d)) {
+        res = mp_add(d, c, d);
+    }
+
+    return res;
+}
+
+/* d = a + b (mod c) - a < c and b < c and positive */
+int mp_addmod_ct(mp_int* a, mp_int* b, mp_int* c, mp_int* d)
+{
+    int res;
+
+    res = mp_add(a, b, d);
+    if (res == MP_OKAY && mp_cmp(d, c) != MP_LT) {
+        res = mp_sub(d, c, d);
+    }
+
+    return res;
+}
+
 /* computes b = a*a */
 int mp_sqr (mp_int * a, mp_int * b)
@@ -3044,5 +3114,5 @@
     if ((digs < (int)MP_WARRAY) &&
         MIN(a->used, b->used) <=
-        (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+        (1L << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
       res = fast_s_mp_mul_digs (a, b, c, digs);
     } else
@@ -3507,5 +3577,5 @@
   if ((digs < (int)MP_WARRAY) &&
       MIN (a->used, b->used) <
-          (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+          (1L << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
     return fast_s_mp_mul_digs (a, b, c, digs);
   }
@@ -4015,5 +4085,5 @@
   if (((a->used + b->used + 1) < (int)MP_WARRAY)
       && MIN (a->used, b->used) <
-      (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+      (1L << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
     return fast_s_mp_mul_high_digs (a, b, c, digs);
   }
@@ -4325,4 +4395,6 @@
   int       res, ix, oldused;
 
+  if (b > MP_MASK) return MP_VAL;
+
   /* grow c as required */
   if (c->alloc < a->used + 1) {
@@ -4512,5 +4584,11 @@
 
      if (w >= b) {
+#ifdef WOLFSSL_LINUXKM
+        t = (mp_digit)w;
+	/* Linux kernel macro for in-place 64 bit integer division. */
+        do_div(t, b);
+#else
         t = (mp_digit)(w / b);
+#endif
         w -= ((mp_word)t) * ((mp_word)b);
       } else {
@@ -4544,5 +4622,5 @@
 #if defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA)
 
-const mp_digit ltm_prime_tab[PRIME_SIZE] = {
+const FLASH_QUALIFIER mp_digit ltm_prime_tab[PRIME_SIZE] = {
   0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
   0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
@@ -4635,19 +4713,19 @@
 #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
 #ifndef WOLFSSL_SP_NO_2048
-  if (mp_count_bits(a) == 1024)
+  if (mp_count_bits(a) == 1024 && mp_isodd(a))
       err = sp_ModExp_1024(b, &r, a, &y);
-  else if (mp_count_bits(a) == 2048)
+  else if (mp_count_bits(a) == 2048 && mp_isodd(a))
       err = sp_ModExp_2048(b, &r, a, &y);
   else
 #endif
 #ifndef WOLFSSL_SP_NO_3072
-  if (mp_count_bits(a) == 1536)
+  if (mp_count_bits(a) == 1536 && mp_isodd(a))
       err = sp_ModExp_1536(b, &r, a, &y);
-  else if (mp_count_bits(a) == 3072)
+  else if (mp_count_bits(a) == 3072 && mp_isodd(a))
       err = sp_ModExp_3072(b, &r, a, &y);
   else
 #endif
 #ifdef WOLFSSL_SP_4096
-  if (mp_count_bits(a) == 4096)
+  if (mp_count_bits(a) == 4096 && mp_isodd(a))
       err = sp_ModExp_4096(b, &r, a, &y);
   else
@@ -5090,6 +5168,6 @@
 
 /* chars used in radix conversions */
-const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\
-                         abcdefghijklmnopqrstuvwxyz+/";
+const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                        "abcdefghijklmnopqrstuvwxyz+/";
 #endif
 
@@ -5179,5 +5257,8 @@
     /* special case for binary */
     if (radix == MP_RADIX_BIN) {
-        *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
+        *size = mp_count_bits(a);
+        if (*size == 0)
+          *size = 1;
+        *size += (a->sign == MP_NEG ? 1 : 0) + 1; /* "-" sign + null term */
         return MP_OKAY;
     }
@@ -5189,5 +5270,10 @@
 
     if (mp_iszero(a) == MP_YES) {
-        *size = 2;
+#ifndef WC_DISABLE_RADIX_ZERO_PAD
+        if (radix == 16)
+            *size = 3;
+        else
+#endif
+            *size = 2;
         return MP_OKAY;
     }
@@ -5195,9 +5281,4 @@
     /* digs is the digit count */
     digs = 0;
-
-    /* if it's negative add one for the sign */
-    if (a->sign == MP_NEG) {
-        ++digs;
-    }
 
     /* init a copy of the input */
@@ -5219,4 +5300,16 @@
     mp_clear (&t);
 
+#ifndef WC_DISABLE_RADIX_ZERO_PAD
+    /* For hexadecimal output, add zero padding when number of digits is odd */
+    if ((digs & 1) && (radix == 16)) {
+        ++digs;
+    }
+#endif
+
+    /* if it's negative add one for the sign */
+    if (a->sign == MP_NEG) {
+        ++digs;
+    }
+
     /* return digs + 1, the 1 is for the NULL byte that would be required. */
     *size = digs + 1;
@@ -5239,4 +5332,9 @@
     /* quick out if its zero */
     if (mp_iszero(a) == MP_YES) {
+#ifndef WC_DISABLE_RADIX_ZERO_PAD
+        if (radix == 16) {
+            *str++ = '0';
+        }
+#endif
         *str++ = '0';
         *str = '\0';
