Move mixed security code to small local functions

The complexity of having functions whose security properties depend on a
runtime argument can be dangerous. Limit risk by isolating such code in
small functions with limited scope.

Signed-off-by: Janos Follath <janos.follath@arm.com>
diff --git a/library/bignum_core.c b/library/bignum_core.c
index ab6cf8f..460a115 100644
--- a/library/bignum_core.c
+++ b/library/bignum_core.c
@@ -746,6 +746,56 @@
     }
 }
 
+/*
+ * This function calculates the indices of the exponent where the exponentiation algorithm should
+ * start processing.
+ *
+ * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
+ * this function is not constant time with respect to the exponent (parameter E).
+ */
+static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E,
+                                                          size_t E_limbs,
+                                                          int E_public,
+                                                          size_t *E_limb_index,
+                                                          size_t *E_bit_index)
+{
+    if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
+        size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs);
+        if (E_bits != 0) {
+            *E_limb_index = E_bits / biL;
+            *E_bit_index = E_bits % biL;
+        }
+    } else {
+        /*
+         * Here we need to be constant time with respect to E and can't do anything better than
+         * start at the first allocated bit.
+         */
+        *E_limb_index = E_limbs;
+        *E_bit_index = 0;
+    }
+}
+
+/*
+ * Warning! If the parameter window_public has MBEDTLS_MPI_IS_PUBLIC as its value, this function is
+ * not constant time with respect to the window parameter and consequently the exponent of the
+ * exponentiation (parameter E of mbedtls_mpi_core_exp_mod_optionally_safe).
+ */
+static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselect,
+                                                        mbedtls_mpi_uint *Wtable,
+                                                        size_t AN_limbs, size_t welem,
+                                                        mbedtls_mpi_uint window,
+                                                        int window_public)
+{
+    if (window_public == MBEDTLS_MPI_IS_PUBLIC) {
+        memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL);
+    } else {
+        /* Select Wtable[window] without leaking window through
+         * memory access patterns. */
+        mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
+                                              AN_limbs, welem, window);
+    }
+}
+
 /* Exponentiation: X := A^E mod N.
  *
  * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
@@ -807,13 +857,8 @@
      * (limb_index=0, E_bit_index=0). */
     size_t E_limb_index = E_limbs;
     size_t E_bit_index = 0;
-    if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
-        size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs);
-        if (E_bits != 0) {
-            E_limb_index = E_bits / biL;
-            E_bit_index = E_bits % biL;
-        }
-    }
+    exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public,
+                                           &E_limb_index, &E_bit_index);
 
     /* At any given time, window contains window_bits bits from E.
      * window_bits can go up to wsize. */
@@ -840,14 +885,9 @@
          * when we've finished processing the exponent. */
         if (window_bits == wsize ||
             (E_bit_index == 0 && E_limb_index == 0)) {
-            if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
-                memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL);
-            } else {
-                /* Select Wtable[window] without leaking window through
-                 * memory access patterns. */
-                mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
-                                                      AN_limbs, welem, window);
-            }
+
+            exp_mod_table_lookup_optionally_safe(Wselect, Wtable, AN_limbs, welem,
+                                                 window, E_public);
             /* Multiply X by the selected element. */
             mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm,
                                      temp);