aboutsummaryrefslogtreecommitdiff
path: root/modexp.c
diff options
context:
space:
mode:
Diffstat (limited to 'modexp.c')
-rw-r--r--modexp.c90
1 files changed, 88 insertions, 2 deletions
diff --git a/modexp.c b/modexp.c
index a5172ee..85b43f5 100644
--- a/modexp.c
+++ b/modexp.c
@@ -1,7 +1,7 @@
/*
* modexp.c
* ----------
- * Wrapper around Cryptech ModExp core.
+ * Wrapper around Cryptech ModExp cores.
*
* This doesn't do full RSA, that's another module. This module's job
* is just the I/O to get bits in and out of the ModExp core, including
@@ -48,6 +48,26 @@
#include "hal_internal.h"
/*
+ * Whether we want to use the new ModExpNG core.
+ */
+
+static int use_modexpng = 0;
+
+hal_error_t hal_modexp_use_modexpng(const int onoff)
+{
+ if (onoff && (hal_core_find(MODEXPNG_NAME, NULL) == NULL))
+ return HAL_ERROR_CORE_NOT_FOUND;
+
+ use_modexpng = onoff;
+ return HAL_OK;
+}
+
+int hal_modexp_using_modexpng(void)
+{
+ return use_modexpng;
+}
+
+/*
* Whether we want debug output.
*/
@@ -182,7 +202,7 @@ static inline hal_error_t check_args(hal_modexp_arg_t *a)
a->exp == NULL || a->exp_len > MODEXPA7_OPERAND_BYTES || a->exp_len > a->mod_len ||
a->mod == NULL || a->mod_len > MODEXPA7_OPERAND_BYTES ||
a->result == NULL || a->result_len > MODEXPA7_OPERAND_BYTES || a->result_len < a->mod_len ||
- a->coeff == NULL || a->coeff_len > MODEXPA7_OPERAND_BYTES ||
+ a->coeff == NULL || a->coeff_len > MODEXPA7_OPERAND_BYTES + 4 ||
a->mont == NULL || a->mont_len > MODEXPA7_OPERAND_BYTES ||
((a->msg_len | a->exp_len | a->mod_len) & 3) != 0)
return HAL_ERROR_BAD_ARGUMENTS;
@@ -342,6 +362,72 @@ hal_error_t hal_modexp2(const int precalc, hal_modexp_arg_t *a1, hal_modexp_arg_
return err;
}
+hal_error_t hal_modexpng(hal_modexpng_arg_t *a)
+{
+ hal_error_t err;
+
+ if ((err = check_args((hal_modexp_arg_t *)a)) != HAL_OK)
+ return err;
+
+ const int free_core = a->core == NULL;
+ const uint32_t mode = (a->p == NULL) ? MODEXPNG_MODE_PLAIN : MODEXPNG_MODE_CRT;
+
+ if ((free_core &&
+ (err = hal_core_alloc(MODEXPNG_NAME, &a->core, NULL)) != HAL_OK) ||
+ (err = hal_io_zero(a->core)) != HAL_OK || // <<<<
+ (err = set_register(a->core, MODEXPNG_ADDR_MODE, mode)) != HAL_OK ||
+ (err = set_register(a->core, MODEXPNG_ADDR_MODULUS_BITS, a->mod_len * 8)) != HAL_OK ||
+ (err = set_register(a->core, MODEXPNG_ADDR_EXPONENT_BITS, a->exp_len * 8)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_M, a->msg, a->msg_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_N, a->mod, a->mod_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_N_FACTOR, a->mont, a->mont_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_N_COEFF, a->coeff, a->coeff_len)) != HAL_OK)
+ goto fail;
+
+ if (a->bf != NULL && a->ubf != NULL) {
+ if ((err = set_buffer(a->core, MODEXPNG_ADDR_BANK_X, a->ubf, a->ubf_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_Y, a->bf, a->bf_len)) != HAL_OK)
+ goto fail;
+ }
+ else {
+ uint8_t one[a->mod_len]; memset(one, 0, sizeof(one)); one[sizeof(one) - 1] = 1;
+ if ((err = set_buffer(a->core, MODEXPNG_ADDR_BANK_X, one, sizeof(one))) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_Y, one, sizeof(one))) != HAL_OK)
+ goto fail;
+ }
+
+ if (mode == MODEXPNG_MODE_PLAIN) {
+ if ((err = set_buffer(a->core, MODEXPNG_ADDR_BANK_D, a->exp, a->exp_len)) != HAL_OK)
+ goto fail;
+ }
+ else {
+ if ((err = set_buffer(a->core, MODEXPNG_ADDR_BANK_P, a->p, a->p_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_DP, a->dP, a->dP_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_P_FACTOR, a->pF, a->pF_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_P_COEFF, a->pC, a->pC_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_Q, a->q, a->q_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_DQ, a->dQ, a->dQ_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_Q_FACTOR, a->qF, a->qF_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_Q_COEFF, a->qC, a->qC_len)) != HAL_OK ||
+ (err = set_buffer(a->core, MODEXPNG_ADDR_BANK_QINV, a->qInv, a->qInv_len)) != HAL_OK)
+ goto fail;
+ }
+
+ if ((err = hal_io_zero(a->core)) != HAL_OK ||
+ (err = hal_io_next(a->core)) != HAL_OK ||
+ (err = hal_io_wait_valid(a->core)) != HAL_OK ||
+ (err = get_buffer(a->core, MODEXPNG_ADDR_BANK_S, a->result, a->result_len)) != HAL_OK)
+ goto fail;
+
+fail:
+ if (free_core) {
+ hal_core_free(a->core);
+ a->core = NULL;
+ }
+
+ return err;
+}
+
/*
* Local variables:
* indent-tabs-mode: nil