[Cryptech-Commits] [sw/libhal] 01/01: Changes to support Pavel's ModExpS6 core.

git at cryptech.is git at cryptech.is
Fri Jul 17 16:13:49 UTC 2015


This is an automated email from the git hooks/post-receive script.

sra at hactrn.net pushed a commit to branch modexps6
in repository sw/libhal.

commit 0915302b7ffa0757be1859d73f14037f338c0253
Author: Rob Austein <sra at hactrn.net>
Date:   Tue Jul 14 00:20:03 2015 -0400

    Changes to support Pavel's ModExpS6 core.
---
 hal.h            |  56 +++++++++++++-----------------
 modexp.c         | 104 +++++++++++++++++++++++++++----------------------------
 rsa.c            |  20 +++++++----
 tests/test-rsa.c |  15 ++++++--
 4 files changed, 103 insertions(+), 92 deletions(-)

diff --git a/hal.h b/hal.h
index 8b731d4..4a31398 100644
--- a/hal.h
+++ b/hal.h
@@ -390,39 +390,33 @@
  * MATH segment.
  */
 
-/* Modexp core */
-#define MODEXP_ADDR_BASE        (SEGMENT_OFFSET_MATH + (0x00 * CORE_SIZE))
-#define MODEXP_ADDR_NAME0       (MODEXP_ADDR_BASE + ADDR_NAME0)
-#define MODEXP_ADDR_NAME1       (MODEXP_ADDR_BASE + ADDR_NAME1)
-#define MODEXP_ADDR_VERSION     (MODEXP_ADDR_BASE + ADDR_VERSION)
-#define MODEXP_ADDR_CTRL        (MODEXP_ADDR_BASE + ADDR_CTRL)
-#define MODEXP_CTRL_INIT_BIT    (1)
-#define MODEXP_CTRL_NEXT_BIT    (2)
-#define MODEXP_ADDR_STATUS      (MODEXP_ADDR_BASE + ADDR_STATUS)
+#define MATH_CORE_SIZE          (0x400)
 
-#define MODEXP_ADDR_DELAY       (MODEXP_ADDR_BASE + 0x13)
-#define MODEXP_STATUS_READY     (1)
-
-#define MODEXP_MODULUS_LENGTH   (MODEXP_ADDR_BASE + 0x20)
-#define MODEXP_EXPONENT_LENGTH  (MODEXP_ADDR_BASE + 0x21)
-#define MODEXP_LENGTH           (MODEXP_ADDR_BASE + 0x22)
-
-#define MODEXP_MODULUS_PTR_RST  (MODEXP_ADDR_BASE + 0x30)
-#define MODEXP_MODULUS_DATA     (MODEXP_ADDR_BASE + 0x31)
-
-#define MODEXP_EXPONENT_PTR_RST (MODEXP_ADDR_BASE + 0x40)
-#define MODEXP_EXPONENT_DATA    (MODEXP_ADDR_BASE + 0x41)
-
-#define MODEXP_MESSAGE_PTR_RST  (MODEXP_ADDR_BASE + 0x50)
-#define MODEXP_MESSAGE_DATA     (MODEXP_ADDR_BASE + 0x51)
-
-#define MODEXP_RESULT_PTR_RST   (MODEXP_ADDR_BASE + 0x60)
-#define MODEXP_RESULT_DATA      (MODEXP_ADDR_BASE + 0x61)
-
-#define MODEXP_NAME0            "mode"
-#define MODEXP_NAME1            "xp  "
-#define MODEXP_VERSION          "0.51"
+/*
+ * ModExpS6 core.  MODEXPS6_OPERAND_BITS is size in bits of largest
+ * supported modulus.
+ */
 
+#define MODEXPS6_ADDR_BASE              (SEGMENT_OFFSET_MATH + (0x00 * MATH_CORE_SIZE))
+#define MODEXPS6_OPERAND_BITS           (4096)
+#define MODEXPS6_OPERAND_WORDS          (MODEXPS6_OPERAND_BITS/32)
+#define MODEXPS6_ADDR_REGISTERS         (MODEXPS6_ADDR_BASE + 0*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_ADDR_OPERANDS          (MODEXPS6_ADDR_BASE + 4*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_ADDR_NAME0             (MODEXPS6_ADDR_REGISTERS + ADDR_NAME0)
+#define MODEXPS6_ADDR_NAME1             (MODEXPS6_ADDR_REGISTERS + ADDR_NAME1)
+#define MODEXPS6_ADDR_VERSION           (MODEXPS6_ADDR_REGISTERS + ADDR_VERSION)
+#define MODEXPS6_ADDR_CTRL              (MODEXPS6_ADDR_REGISTERS + ADDR_CTRL)
+#define MODEXPS6_ADDR_STATUS            (MODEXPS6_ADDR_REGISTERS + ADDR_STATUS)
+#define MODEXPS6_ADDR_MODE              (MODEXPS6_ADDR_REGISTERS + 0x10)
+#define MODEXPS6_ADDR_MODULUS_WIDTH     (MODEXPS6_ADDR_REGISTERS + 0x11)
+#define MODEXPS6_ADDR_EXPONENT_WIDTH    (MODEXPS6_ADDR_REGISTERS + 0x12)
+#define MODEXPS6_ADDR_MODULUS           (MODEXPS6_ADDR_OPERANDS + 0*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_ADDR_MESSAGE           (MODEXPS6_ADDR_OPERANDS + 1*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_ADDR_EXPONENT          (MODEXPS6_ADDR_OPERANDS + 2*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_ADDR_RESULT            (MODEXPS6_ADDR_OPERANDS + 3*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_NAME0                  "mode"
+#define MODEXPS6_NAME1                  "xps6"
+#define MODEXPS6_VERSION                "0.10"
 
 /*
  * C API error codes.  Defined in this form so we can keep the tokens
diff --git a/modexp.c b/modexp.c
index 1e3d292..11a8d21 100644
--- a/modexp.c
+++ b/modexp.c
@@ -91,60 +91,41 @@ static hal_error_t set_register(const off_t addr,
 }
 
 /*
- * Get value of a block memory.
+ * Get value of a data buffer.  We reverse the order of 32-bit words
+ * in the buffer during the transfer to match what the modexps6 core
+ * expects.
  */
 
-static hal_error_t get_blockmem(const off_t reset_addr,
-                                const off_t data_addr,
-                                uint8_t *value,
-                                const size_t length,
-                                const size_t io_len)
+static hal_error_t get_buffer(const off_t data_addr,
+                              uint8_t *value,
+                              const size_t length)
 {
-  uint8_t discard[4];
   size_t i;
 
   assert(value != NULL && length % 4 == 0);
 
-  assert(io_len >= length && io_len % 4 == 0);
-
-  check(set_register(reset_addr, 1));
-
-  for (i = 0; i < io_len - length; i += 4) {
-    check(hal_io_read(data_addr, discard, 4));
-    if (discard[0] != 0 || discard[1] != 0 || discard[2] != 0 || discard[3] != 0)
-      return HAL_ERROR_IO_UNEXPECTED;
-  }
-
   for (i = 0; i < length; i += 4)
-    check(hal_io_read(data_addr, &value[i], 4));
+    check(hal_io_read(data_addr + i/4, &value[length - 4 - i], 4));
 
   return HAL_OK;
 }
 
 /*
- * Set value of a block memory.
+ * Set value of a data buffer.  We reverse the order of 32-bit words
+ * in the buffer during the transfer to match what the modexps6 core
+ * expects.
  */
 
-static hal_error_t set_blockmem(const off_t reset_addr,
-                                const off_t data_addr,
-                                const uint8_t * const value,
-                                const size_t length,
-                                const size_t io_len)
+static hal_error_t set_buffer(const off_t data_addr,
+                              const uint8_t * const value,
+                              const size_t length)
 {
-  const uint8_t zero[4] = { 0, 0, 0, 0 };
   size_t i;
 
   assert(value != NULL && length % 4 == 0);
 
-  assert(io_len >= length && io_len % 4 == 0);
-
-  check(set_register(reset_addr, 1));
-
-  for (i = 0; i < io_len - length; i += 4)
-    check(hal_io_write(data_addr, zero, 4));
-
   for (i = 0; i < length; i += 4)
-    check(hal_io_write(data_addr, &value[i], 4));
+    check(hal_io_write(data_addr + i/4, &value[length - 4 - i], 4));
 
   return HAL_OK;
 }
@@ -175,35 +156,52 @@ hal_error_t hal_modexp(const uint8_t * const msg, const size_t msg_len, /* Messa
     return HAL_ERROR_BAD_ARGUMENTS;
 
   /*
-   * This insanity is a work-around for a current bug in the ModExp
-   * core: we have to zero-pad everything out to the size of the
-   * modulus plus 32-bits.  Some kind of overflow issue.  All of this
-   * "io_len" nonsense can go away once that's fixed.
+   * We probably ought to take the mode (fast vs constant-time) as an
+   * argument, but for the moment we just guess that really short
+   * exponent means we're using the public key and can use fast mode,
+   * all other cases are something to do with the private key and
+   * therefore must use constant-time mode.
+   *
+   * Unclear whether it's worth trying to figure out exactly how long
+   * the operands are: assuming a multiple of eight is safe, but makes
+   * a bit more work for the core; checking to see how many bits are
+   * really set leaves the core sitting idle while the main CPU does
+   * these checks.  No way to know which is faster without testing;
+   * take simple approach for the moment.
    */
 
-  const size_t io_len = mod_len + 4;
-  assert((io_len & 3) == 0);
+  /* Select mode (1 = fast, 0 = safe) */
+  check(set_register(MODEXPS6_ADDR_MODE, (exp_len <= 4)));
 
-  check(set_blockmem(MODEXP_MODULUS_PTR_RST, MODEXP_MODULUS_DATA, mod, mod_len, io_len));
-  check(set_blockmem(MODEXP_MESSAGE_PTR_RST, MODEXP_MESSAGE_DATA, msg, msg_len, io_len));
-  check(set_register(MODEXP_MODULUS_LENGTH, /* mod_len */ io_len / 4));
+  /* Set modulus size in bits */
+  check(set_register(MODEXPS6_ADDR_MODULUS_WIDTH, mod_len * 8));
 
-  check(set_blockmem(MODEXP_EXPONENT_PTR_RST, MODEXP_EXPONENT_DATA, exp, exp_len, exp_len));
-  check(set_register(MODEXP_EXPONENT_LENGTH, exp_len / 4));
+  /* Write new modulus */
+  check(set_buffer(MODEXPS6_ADDR_MODULUS, mod, mod_len));
 
-  check(hal_io_wait_ready(MODEXP_ADDR_STATUS));
+  /* Pre-calcuate speed-up coefficient */
+  check(hal_io_init(MODEXPS6_ADDR_CTRL));
 
-  check(set_register(MODEXP_ADDR_CTRL, 1));
+  /* Wait for calculation to complete */
+  check(hal_io_wait_ready(MODEXPS6_ADDR_STATUS));
 
-  /*
-   * ModExp core is not very fast (yet), so wait a long time for a
-   * response, but not forever.
-   */
+  /* Write new message */
+  check(set_buffer(MODEXPS6_ADDR_MESSAGE, msg, msg_len));
+
+  /* Set new exponent length in bits */
+  check(set_register(MODEXPS6_ADDR_EXPONENT_WIDTH, exp_len * 8));
+
+  /* Set new exponent */
+  check(set_buffer(MODEXPS6_ADDR_EXPONENT, exp, exp_len));
+
+  /* Start calculation */
+  check(hal_io_next(MODEXPS6_ADDR_CTRL));
 
-  int timeout = 0x7FFFFFFF;
-  check(hal_io_wait(MODEXP_ADDR_STATUS, STATUS_READY, &timeout));
+  /* Wait for result */
+  check(hal_io_wait_valid(MODEXPS6_ADDR_STATUS));
 
-  check(get_blockmem(MODEXP_RESULT_PTR_RST, MODEXP_RESULT_DATA, result, mod_len, io_len));
+  /* Extract result */
+  check(get_buffer(MODEXPS6_ADDR_RESULT, result, mod_len));
 
   return HAL_OK;
 }
diff --git a/rsa.c b/rsa.c
index b05dec7..2e950b8 100644
--- a/rsa.c
+++ b/rsa.c
@@ -55,7 +55,7 @@
  */
 
 #ifndef HAL_RSA_USE_MODEXP
-#define HAL_RSA_USE_MODEXP 0
+#define HAL_RSA_USE_MODEXP 1
 #endif
 
 /*
@@ -170,13 +170,21 @@ static hal_error_t modexp(fp_int *msg, fp_int *exp, fp_int *mod, fp_int *res)
 
   assert(msg != NULL && exp != NULL && mod != NULL && res != NULL);
 
-  const size_t msg_len = fp_unsigned_bin_size(msg);
-  const size_t exp_len = fp_unsigned_bin_size(exp);
-  const size_t mod_len = fp_unsigned_bin_size(mod);
+  fp_int reduced_msg;
 
-  const size_t len = (MAX(MAX(msg_len, exp_len), mod_len) + 3) & ~3;
+  if (fp_cmp_mag(msg, mod) != FP_LT) {
+    fp_init(&reduced_msg);
+    fp_mod(msg, mod, &reduced_msg);
+    msg = &reduced_msg;
+  }
+
+  const size_t exp_len = (fp_unsigned_bin_size(exp) + 3) & ~3;
+  const size_t mod_len = (fp_unsigned_bin_size(mod) + 3) & ~3;
 
-  uint8_t msgbuf[len], expbuf[len], modbuf[len], resbuf[len];
+  uint8_t msgbuf[mod_len];
+  uint8_t expbuf[exp_len];
+  uint8_t modbuf[mod_len];
+  uint8_t resbuf[mod_len];
 
   if ((err = unpack_fp(msg, msgbuf, sizeof(msgbuf))) != HAL_OK ||
       (err = unpack_fp(exp, expbuf, sizeof(expbuf))) != HAL_OK ||
diff --git a/tests/test-rsa.c b/tests/test-rsa.c
index 0fd2002..4b4d7b3 100644
--- a/tests/test-rsa.c
+++ b/tests/test-rsa.c
@@ -271,9 +271,15 @@ static int test_rsa(const rsa_tc_t * const tc)
   /* RSA decyrption using CRT */
   time_check(test_decrypt("Signature (CRT)", tc));
 
+#if 1
+#warning Key generation tests disabled
+#else
+
   /* Key generation and CRT -- not test vector, so writes key and sig to file */
   time_check(test_gen("Generation and CRT", tc));
 
+#endif
+
   return ok;
 }
 
@@ -287,8 +293,8 @@ int main(int argc, char *argv[])
    * Initialize EIM and report what core we're running.
    */
 
-  if ((err = hal_io_read(MODEXP_ADDR_NAME0,   name,    sizeof(name)))    != HAL_OK ||
-      (err = hal_io_read(MODEXP_ADDR_VERSION, version, sizeof(version))) != HAL_OK) {
+  if ((err = hal_io_read(MODEXPS6_ADDR_NAME0,   name,    sizeof(name)))    != HAL_OK ||
+      (err = hal_io_read(MODEXPS6_ADDR_VERSION, version, sizeof(version))) != HAL_OK) {
     printf("Initialization failed: %s\n", hal_error_string(err));
     return 1;
   }
@@ -301,6 +307,11 @@ int main(int argc, char *argv[])
 
   hal_modexp_set_debug(1);
 
+#if 1
+#warning RSA blinding disabled
+  hal_rsa_set_blinding(0);
+#endif
+
   /* Normal test */
 
   for (i = 0; i < (sizeof(rsa_tc)/sizeof(*rsa_tc)); i++)



More information about the Commits mailing list