diff options
Diffstat (limited to 'modexp.c')
-rw-r--r-- | modexp.c | 90 |
1 files changed, 88 insertions, 2 deletions
@@ -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 |