aboutsummaryrefslogtreecommitdiff
path: root/ecdsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'ecdsa.c')
-rw-r--r--ecdsa.c109
1 files changed, 97 insertions, 12 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
/*