[Cryptech-Commits] [sw/libhal] 01/04: Refactor to add P384 support. Untested.

git at cryptech.is git at cryptech.is
Fri Mar 3 13:34:02 UTC 2017


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

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

commit 9afc5d0b081983779439aa6f91781efb3e56d01d
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Thu Mar 2 17:23:02 2017 -0500

    Refactor to add P384 support.  Untested.
---
 ecdsa.c             | 109 ++++++++++++++++++++++++++++++++++++++++++++++------
 hal.h               |   3 ++
 verilog_constants.h |  26 +++++++++----
 3 files changed, 119 insertions(+), 19 deletions(-)

diff --git a/ecdsa.c b/ecdsa.c
index 42ea307..bb585be 100644
--- a/ecdsa.c
+++ b/ecdsa.c
@@ -101,6 +101,25 @@ static int verilog_ecdsa256_multiplier = 1;
 #endif
 
 /*
+ * Whether to use experimental Verilog ECDSA-P384 point multiplier.
+ */
+
+#ifndef HAL_ECDSA_VERILOG_ECDSA384_MULTIPLIER
+#define HAL_ECDSA_VERILOG_ECDSA384_MULTIPLIER 1
+#endif
+
+#if HAL_ECDSA_VERILOG_ECDSA384_MULTIPLIER
+static int verilog_ecdsa384_multiplier = 1;
+#endif
+
+/*
+ * Whether to include Verilog point multiplier code at all.
+ */
+
+#define HAL_ECDSA_ANY_VERILOG_MULTIPLIER \
+  (HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER | HAL_ECDSA_VERILOG_ECDSA384_MULTIPLIER)
+
+/*
  * Whether we want debug output.
  */
 
@@ -136,6 +155,7 @@ typedef struct {
   fp_digit rho;                         /* Montgomery reduction value */
   const uint8_t *oid;                   /* OBJECT IDENTIFIER */
   size_t oid_len;                       /* Length of OBJECT IDENTIFIER */
+  hal_curve_name_t curve;               /* Curve name */
 } ecdsa_curve_t;
 
 /*
@@ -218,6 +238,7 @@ static const ecdsa_curve_t * const get_curve(const hal_curve_name_t curve)
     fp_montgomery_calc_normalization(curve_p256.mu, curve_p256.q);
     curve_p256.oid = p256_oid;
     curve_p256.oid_len = sizeof(p256_oid);
+    curve_p256.curve = HAL_CURVE_P256;
 
     fp_read_unsigned_bin(curve_p384.q,  unconst_uint8_t(p384_q),  sizeof(p384_q));
     fp_read_unsigned_bin(curve_p384.b,  unconst_uint8_t(p384_b),  sizeof(p384_b));
@@ -230,6 +251,7 @@ static const ecdsa_curve_t * const get_curve(const hal_curve_name_t curve)
     fp_montgomery_calc_normalization(curve_p384.mu, curve_p384.q);
     curve_p384.oid = p384_oid;
     curve_p384.oid_len = sizeof(p384_oid);
+    curve_p384.curve = HAL_CURVE_P384;
 
     fp_read_unsigned_bin(curve_p521.q,  unconst_uint8_t(p521_q),  sizeof(p521_q));
     fp_read_unsigned_bin(curve_p521.b,  unconst_uint8_t(p521_b),  sizeof(p521_b));
@@ -242,6 +264,7 @@ static const ecdsa_curve_t * const get_curve(const hal_curve_name_t curve)
     fp_montgomery_calc_normalization(curve_p521.mu, curve_p521.q);
     curve_p521.oid = p521_oid;
     curve_p521.oid_len = sizeof(p521_oid);
+    curve_p521.curve = HAL_CURVE_P521;
 
     initialized = 1;
   }
@@ -761,20 +784,30 @@ static inline hal_error_t get_random(void *buffer, const size_t length)
 #endif /* HAL_ECDSA_DEBUG_ONLY_STATIC_TEST_VECTOR_RANDOM */
 
 /*
- * Use experimental Verilog base point multiplier core to calculate
+ * Use experimental Verilog base point multiplier cores to calculate
  * public key given a private key.  point_pick_random() has already
  * selected a suitable private key for us, we just need to calculate
  * the corresponding public key.
  */
 
-#if HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER
+#if HAL_ECDSA_ANY_VERILOG_MULTIPLIER
 
-static hal_error_t verilog_point_pick_random(fp_int *k, ec_point_t *P)
+typedef struct {
+  size_t bytes;
+  const char *name;
+  hal_addr_t k_addr;
+  hal_addr_t x_addr;
+  hal_addr_t y_addr;
+} verilog_ecdsa_driver_t;
+
+static hal_error_t verilog_point_pick_random(const verilog_ecdsa_driver_t * const driver,
+                                             fp_int *k,
+                                             ec_point_t *P)
 {
   assert(k != NULL && P != NULL);
 
   const size_t len = fp_unsigned_bin_size(k);
-  uint8_t b[ECDSA256_OPERAND_BITS / 8];
+  uint8_t b[driver->bytes];
   const uint8_t zero[4] = {0, 0, 0, 0};
   hal_core_t *core = NULL;
   hal_error_t err;
@@ -782,7 +815,7 @@ static hal_error_t verilog_point_pick_random(fp_int *k, ec_point_t *P)
   if (len > sizeof(b))
     return HAL_ERROR_RESULT_TOO_LONG;
 
-  if ((err = hal_core_alloc(ECDSA256_NAME, &core)) != HAL_OK)
+  if ((err = hal_core_alloc(driver->name, &core)) != HAL_OK)
     goto fail;
 
 #define check(_x_) do { if ((err = (_x_)) != HAL_OK) goto fail; } while (0)
@@ -791,18 +824,18 @@ static hal_error_t verilog_point_pick_random(fp_int *k, ec_point_t *P)
   fp_to_unsigned_bin(k, b + sizeof(b) - len);
 
   for (int i = 0; i < sizeof(b); i += 4)
-    check(hal_io_write(core, ECDSA256_ADDR_K + i/4, &b[sizeof(b) - 4 - i], 4));
+    check(hal_io_write(core, driver->k_addr + i/4, &b[sizeof(b) - 4 - i], 4));
 
   check(hal_io_write(core, ADDR_CTRL, zero, sizeof(zero)));
   check(hal_io_next(core));
   check(hal_io_wait_ready(core));
 
   for (int i = 0; i < sizeof(b); i += 4)
-    check(hal_io_read(core, ECDSA256_ADDR_X + i/4, &b[sizeof(b) - 4 - i], 4));
+    check(hal_io_read(core, driver->x_addr + i/4, &b[sizeof(b) - 4 - i], 4));
   fp_read_unsigned_bin(P->x, b, sizeof(b));
 
   for (int i = 0; i < sizeof(b); i += 4)
-    check(hal_io_read(core, ECDSA256_ADDR_Y + i/4, &b[sizeof(b) - 4 - i], 4));
+    check(hal_io_read(core, driver->y_addr + i/4, &b[sizeof(b) - 4 - i], 4));
   fp_read_unsigned_bin(P->y, b, sizeof(b));
 
   fp_set(P->z, 1);
@@ -819,6 +852,46 @@ static hal_error_t verilog_point_pick_random(fp_int *k, ec_point_t *P)
 
 #endif
 
+static inline hal_error_t verilog_p256_point_pick_random(fp_int *k, ec_point_t *P)
+{
+#if HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER
+
+  static const verilog_ecdsa_driver_t verilog_p256_driver = {
+      .name   = ECDSA256_NAME,
+      .bytes  = ECDSA256_OPERAND_BITS / 8,
+      .k_addr = ECDSA256_ADDR_K,
+      .x_addr = ECDSA256_ADDR_X,
+      .y_addr = ECDSA256_ADDR_Y
+  };
+
+  if (verilog_ecdsa256_multiplier)
+    return verilog_point_pick_random(&verilog_p256_driver, k, P);
+
+#endif
+
+  return HAL_ERROR_CORE_NOT_FOUND;
+}
+
+static inline hal_error_t verilog_p384_point_pick_random(fp_int *k, ec_point_t *P)
+{
+#if HAL_ECDSA_VERILOG_ECDSA384_MULTIPLIER
+
+  static const verilog_ecdsa_driver_t verilog_p384_driver = {
+    .name   = ECDSA384_NAME,
+    .bytes  = ECDSA384_OPERAND_BITS / 8,
+    .k_addr = ECDSA384_ADDR_K,
+    .x_addr = ECDSA384_ADDR_X,
+    .y_addr = ECDSA384_ADDR_Y
+  };
+
+  if (verilog_ecdsa256_multiplier)
+    return verilog_point_pick_random(&verilog_p256_driver, k, P);
+
+#endif
+
+  return HAL_ERROR_CORE_NOT_FOUND;
+}
+
 /*
  * Pick a random point on the curve, return random scalar and
  * resulting point.
@@ -863,10 +936,22 @@ static hal_error_t point_pick_random(const ecdsa_curve_t * const curve,
 
   memset(k_buf, 0, sizeof(k_buf));
 
-#if HAL_ECDSA_VERILOG_ECDSA256_MULTIPLIER
-  if (verilog_ecdsa256_multiplier && curve == get_curve(HAL_CURVE_P256) &&
-      (err = verilog_point_pick_random(k, P)) != HAL_ERROR_CORE_NOT_FOUND)
-    return err;
+#if HAL_ECDSA_ANY_VERILOG_MULTIPLIER
+  switch (curve->curve) {
+
+  case HAL_CURVE_P256:
+    if ((err = verilog_p256_point_pick_random(k, P)) != HAL_ERROR_CORE_NOT_FOUND)
+      return err;
+  break;
+
+  case HAL_CURVE_P384:
+    if ((err = verilog_p384_point_pick_random(k, P)) != HAL_ERROR_CORE_NOT_FOUND)
+      return err;
+  break;
+
+  default:
+    break;
+  }
 #endif
 
   /*
diff --git a/hal.h b/hal.h
index b1a217a..7b4fcb7 100644
--- a/hal.h
+++ b/hal.h
@@ -106,6 +106,9 @@
 #define ECDSA256_NAME           "ecdsa256"
 #define ECDSA256_VERSION        "0.11"
 
+#define ECDSA256_NAME           "ecdsa384"
+#define ECDSA256_VERSION        "0.11"
+
 /*
  * C API error codes.  Defined in this form so we can keep the tokens
  * and error strings together.  See errorstrings.c.
diff --git a/verilog_constants.h b/verilog_constants.h
index 900785c..c9bb566 100644
--- a/verilog_constants.h
+++ b/verilog_constants.h
@@ -241,7 +241,7 @@
 #define MODEXPA7_ADDR_RESULT            (MODEXPA7_ADDR_OPERANDS + 3 * MODEXPA7_OPERAND_WORDS)
 
 /*
- * ECDSA P-256 point mulitipler core.  ECDSA256_OPERAND_BITS is size
+ * ECDSA P-256 point multiplier core.  ECDSA256_OPERAND_BITS is size
  * in bits of the (only) supported operand size (256 bits, imagine that).
  *
  * (Not sure which category EC Point Mulitiplier will end up in, but
@@ -249,12 +249,24 @@
  */
 
 #define ECDSA256_OPERAND_BITS           (256)
-#define ECDSA256_OPERAND_WORDS          (ECDSA256_OPERAND_BITS / 32)
-#define ECDSA256_ADDR_REGISTERS         (0 * ECDSA256_OPERAND_WORDS)
-#define ECDSA256_ADDR_OPERANDS          (4 * ECDSA256_OPERAND_WORDS)
-#define ECDSA256_ADDR_K                 (ECDSA256_ADDR_OPERANDS + 0 * ECDSA256_OPERAND_WORDS)
-#define ECDSA256_ADDR_X                 (ECDSA256_ADDR_OPERANDS + 1 * ECDSA256_OPERAND_WORDS)
-#define ECDSA256_ADDR_Y                 (ECDSA256_ADDR_OPERANDS + 2 * ECDSA256_OPERAND_WORDS)
+#define ECDSA256_ADDR_REGISTERS         (0x00)
+#define ECDSA256_ADDR_K                 (0x20)
+#define ECDSA256_ADDR_X                 (0x28)
+#define ECDSA256_ADDR_Y                 (0x30)
+
+/*
+ * ECDSA P-384 point multiplier core.  ECDSA384_OPERAND_BITS is size
+ * in bits of the (only) supported operand size (384 bits, imagine that).
+ *
+ * (Not sure which category EC Point Mulitiplier will end up in, but
+ * let's pretend it's "math".)
+ */
+
+#define ECDSA384_OPERAND_BITS           (384)
+#define ECDSA384_ADDR_REGISTERS         (0x00)
+#define ECDSA384_ADDR_K                 (0x40)
+#define ECDSA384_ADDR_X                 (0x50)
+#define ECDSA384_ADDR_Y                 (0x60)
 
 /*
  * Utility cores.



More information about the Commits mailing list