aboutsummaryrefslogtreecommitdiff
path: root/rsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'rsa.c')
-rw-r--r--rsa.c164
1 files changed, 117 insertions, 47 deletions
diff --git a/rsa.c b/rsa.c
index b0c34c5..4b90ecc 100644
--- a/rsa.c
+++ b/rsa.c
@@ -12,8 +12,9 @@
* St Denis's libtomcrypt code.
*
* Authors: Rob Austein
- * Copyright (c) 2015-2018, NORDUnet A/S
- * All rights reserved.
+ * Copyright (c) 2015-2018, NORDUnet A/S All rights reserved.
+ * Copyright: 2020, The Commons Conservancy Cryptech Project
+ * SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -25,9 +26,9 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * - Neither the name of the NORDUnet nor the names of its contributors may
- * be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * - Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -76,6 +77,13 @@
#include <tfm.h>
#include "asn1_internal.h"
+#ifdef DO_TIMING
+#include "stm-dwt.h"
+#else
+#define DWT_start(x)
+#define DWT_stop(x)
+#endif
+
/*
* Whether to use ModExp core. It works, but it's painfully slow.
*/
@@ -153,6 +161,13 @@ static struct {
#endif
+void hal_rsa_clear_blinding_cache(void)
+{
+#if HAL_RSA_BLINDING_CACHE_SIZE > 0
+ memset(&bfc, 0, sizeof(bfc));
+#endif
+}
+
/*
* RSA key implementation. This structure type is private to this
* module, anything else that needs to touch one of these just gets a
@@ -235,7 +250,7 @@ static hal_error_t unpack_fp(const fp_int * const bn, uint8_t *buffer, const siz
#if HAL_RSA_SIGN_USE_MODEXP
-static hal_error_t modexp_precalc(const fp_int *modulus, uint8_t *coeff, size_t coeff_len, uint8_t *factor, size_t factor_len)
+static hal_error_t modexpng_precalc(const fp_int *modulus, uint8_t *coeff, size_t coeff_len, uint8_t *factor, size_t factor_len)
{
const size_t keylen = ((fp_unsigned_bin_size(unconst_fp_int(modulus)) + 3) & ~3) * 8;
hal_error_t err;
@@ -294,13 +309,21 @@ static hal_error_t modexp(hal_core_t *core,
.mont = mont, .mont_len = mont_len
};
- if ((precalc &&
- (err = modexp_precalc(mod, coeff, coeff_len, mont, mont_len)) != HAL_OK) ||
- (err = unpack_fp(msg, msgbuf, sizeof(msgbuf))) != HAL_OK ||
+ if (precalc) {
+ DWT_start(DWT_precalc_n);
+ if ((err = modexpng_precalc(mod, coeff, coeff_len, mont, mont_len)) != HAL_OK)
+ goto fail;
+ DWT_stop(DWT_precalc_n);
+ }
+
+ if ((err = unpack_fp(msg, msgbuf, sizeof(msgbuf))) != HAL_OK ||
(err = unpack_fp(exp, expbuf, sizeof(expbuf))) != HAL_OK ||
- (err = unpack_fp(mod, modbuf, sizeof(modbuf))) != HAL_OK ||
- (err = hal_modexpng(&args)) != HAL_OK)
+ (err = unpack_fp(mod, modbuf, sizeof(modbuf))) != HAL_OK)
goto fail;
+ DWT_start(DWT_hal_modexpng_n);
+ if ((err = hal_modexpng(&args)) != HAL_OK)
+ goto fail;
+ DWT_stop(DWT_hal_modexpng_n);
}
else {
hal_modexp_arg_t args = {
@@ -315,9 +338,12 @@ static hal_error_t modexp(hal_core_t *core,
if ((err = unpack_fp(msg, msgbuf, sizeof(msgbuf))) != HAL_OK ||
(err = unpack_fp(exp, expbuf, sizeof(expbuf))) != HAL_OK ||
- (err = unpack_fp(mod, modbuf, sizeof(modbuf))) != HAL_OK ||
- (err = hal_modexp(precalc, &args)) != HAL_OK)
+ (err = unpack_fp(mod, modbuf, sizeof(modbuf))) != HAL_OK)
+ goto fail;
+ DWT_start(DWT_hal_modexp);
+ if ((err = hal_modexp(precalc, &args)) != HAL_OK)
goto fail;
+ DWT_stop(DWT_hal_modexp);
}
fp_read_unsigned_bin(res, resbuf, sizeof(resbuf));
@@ -362,33 +388,38 @@ static hal_error_t modexp2(const int precalc,
uint8_t expbuf1[exp1_len], modbuf1[mod1_len], resbuf1[mod1_len];
uint8_t expbuf2[exp2_len], modbuf2[mod2_len], resbuf2[mod2_len];
- hal_modexp_arg_t args1 = {
- .core = core1,
- .msg = msgbuf, .msg_len = sizeof(msgbuf),
- .exp = expbuf1, .exp_len = sizeof(expbuf1),
- .mod = modbuf1, .mod_len = sizeof(modbuf1),
- .result = resbuf1, .result_len = sizeof(resbuf1),
- .coeff = coeff1, .coeff_len = coeff1_len,
- .mont = mont1, .mont_len = mont1_len
- };
+ hal_modexp_arg_t args1 = {
+ .core = core1,
+ .msg = msgbuf, .msg_len = sizeof(msgbuf),
+ .exp = expbuf1, .exp_len = sizeof(expbuf1),
+ .mod = modbuf1, .mod_len = sizeof(modbuf1),
+ .result = resbuf1, .result_len = sizeof(resbuf1),
+ .coeff = coeff1, .coeff_len = coeff1_len,
+ .mont = mont1, .mont_len = mont1_len
+ };
- hal_modexp_arg_t args2 = {
- .core = core2,
- .msg = msgbuf, .msg_len = sizeof(msgbuf),
- .exp = expbuf2, .exp_len = sizeof(expbuf2),
- .mod = modbuf2, .mod_len = sizeof(modbuf2),
- .result = resbuf2, .result_len = sizeof(resbuf2),
- .coeff = coeff2, .coeff_len = coeff2_len,
- .mont = mont2, .mont_len = mont2_len
- };
+ hal_modexp_arg_t args2 = {
+ .core = core2,
+ .msg = msgbuf, .msg_len = sizeof(msgbuf),
+ .exp = expbuf2, .exp_len = sizeof(expbuf2),
+ .mod = modbuf2, .mod_len = sizeof(modbuf2),
+ .result = resbuf2, .result_len = sizeof(resbuf2),
+ .coeff = coeff2, .coeff_len = coeff2_len,
+ .mont = mont2, .mont_len = mont2_len
+ };
+ DWT_start(DWT_unpack_fp);
if ((err = unpack_fp(msg, msgbuf, sizeof(msgbuf))) != HAL_OK ||
(err = unpack_fp(exp1, expbuf1, sizeof(expbuf1))) != HAL_OK ||
(err = unpack_fp(mod1, modbuf1, sizeof(modbuf1))) != HAL_OK ||
(err = unpack_fp(exp2, expbuf2, sizeof(expbuf2))) != HAL_OK ||
- (err = unpack_fp(mod2, modbuf2, sizeof(modbuf2))) != HAL_OK ||
- (err = hal_modexp2(precalc, &args1, &args2)) != HAL_OK)
+ (err = unpack_fp(mod2, modbuf2, sizeof(modbuf2))) != HAL_OK)
goto fail;
+ DWT_stop(DWT_unpack_fp);
+ DWT_start(DWT_hal_modexp2);
+ if ((err = hal_modexp2(precalc, &args1, &args2)) != HAL_OK)
+ goto fail;
+ DWT_stop(DWT_hal_modexp2);
fp_read_unsigned_bin(res1, resbuf1, sizeof(resbuf1));
fp_read_unsigned_bin(res2, resbuf2, sizeof(resbuf2));
@@ -419,15 +450,19 @@ static hal_error_t modexpng(hal_core_t *core,
return HAL_ERROR_IMPOSSIBLE;
if (!(key->flags & RSA_FLAG_PRECALC_N_DONE)) {
- if ((err = modexp_precalc(key->n, key->nC, sizeof(key->nC), key->nF, sizeof(key->nF))) != HAL_OK)
+ DWT_start(DWT_precalc_n);
+ if ((err = modexpng_precalc(key->n, key->nC, sizeof(key->nC), key->nF, sizeof(key->nF))) != HAL_OK)
return err;
+ DWT_stop(DWT_precalc_n);
key->flags |= RSA_FLAG_PRECALC_N_DONE | RSA_FLAG_NEEDS_SAVING;
}
if (key->p && !(key->flags & RSA_FLAG_PRECALC_PQ_DONE)) {
- if ((err = modexp_precalc(key->p, key->pC, sizeof(key->pC), key->pF, sizeof(key->pF))) != HAL_OK ||
- (err = modexp_precalc(key->q, key->qC, sizeof(key->qC), key->qF, sizeof(key->qF))) != HAL_OK)
+ DWT_start(DWT_precalc_pq);
+ if ((err = modexpng_precalc(key->p, key->pC, sizeof(key->pC), key->pF, sizeof(key->pF))) != HAL_OK ||
+ (err = modexpng_precalc(key->q, key->qC, sizeof(key->qC), key->qF, sizeof(key->qF))) != HAL_OK)
return err;
+ DWT_stop(DWT_precalc_pq);
key->flags |= RSA_FLAG_PRECALC_PQ_DONE | RSA_FLAG_NEEDS_SAVING;
}
@@ -469,6 +504,7 @@ static hal_error_t modexpng(hal_core_t *core,
.ubf = ubf_buf, .ubf_len = sizeof(ubf_buf),
};
+ DWT_start(DWT_unpack_fp);
if (bf) {
if ((err = unpack_fp(bf, bf_buf, sizeof(bf_buf))) != HAL_OK ||
(err = unpack_fp(ubf, ubf_buf, sizeof(ubf_buf))) != HAL_OK)
@@ -487,12 +523,16 @@ static hal_error_t modexpng(hal_core_t *core,
(err = unpack_fp(key->q, q_buf, sizeof(q_buf))) != HAL_OK ||
(err = unpack_fp(key->u, u_buf, sizeof(u_buf))) != HAL_OK ||
(err = unpack_fp(key->dP, dP_buf, sizeof(dP_buf))) != HAL_OK ||
- (err = unpack_fp(key->dQ, dQ_buf, sizeof(dQ_buf))) != HAL_OK ||
- (err = hal_modexpng(&args)) != HAL_OK)
+ (err = unpack_fp(key->dQ, dQ_buf, sizeof(dQ_buf))) != HAL_OK)
goto fail;
+ DWT_stop(DWT_unpack_fp);
+ DWT_start(DWT_hal_modexpng);
+ if ((err = hal_modexpng(&args)) != HAL_OK)
+ goto fail;
+ DWT_stop(DWT_hal_modexpng);
fp_read_unsigned_bin(res, resbuf, sizeof(resbuf));
- /* we do the blinding factor permutation in create_blinding_factors,
+ /* we do the blinding factor mutation in create_blinding_factors,
* so we don't need to read them back from the core
*/
@@ -575,7 +615,7 @@ static hal_error_t modexpng(hal_core_t *core,
return HAL_ERROR_FORBIDDEN;
}
-static hal_error_t modexp_precalc(const fp_int *modulus, uint8_t *coeff, const size_t coeff_len, uint8_t *factor, const size_t factor_len)
+static hal_error_t modexpng_precalc(const fp_int *modulus, uint8_t *coeff, const size_t coeff_len, uint8_t *factor, const size_t factor_len)
{
return HAL_ERROR_FORBIDDEN;
}
@@ -648,17 +688,21 @@ static hal_error_t create_blinding_factors(hal_rsa_key_t *key, fp_int *bf, fp_in
}
#endif
+ DWT_start(DWT_hal_get_random);
if ((err = hal_get_random(NULL, rnd, sizeof(rnd))) != HAL_OK)
goto fail;
+ DWT_stop(DWT_hal_get_random);
fp_init(bf);
fp_read_unsigned_bin(bf, rnd, sizeof(rnd));
fp_copy(bf, ubf);
/* bf = ubf ** e mod n */
+ DWT_start(DWT_modexp);
if ((err = modexp(NULL, precalc, bf, key->e, key->n, bf,
key->nC, sizeof(key->nC), key->nF, sizeof(key->nF))) != HAL_OK)
goto fail;
+ DWT_stop(DWT_modexp);
if (precalc)
key->flags |= RSA_FLAG_PRECALC_N_DONE | RSA_FLAG_NEEDS_SAVING;
@@ -696,12 +740,20 @@ static hal_error_t rsa_crt(hal_core_t *core1, hal_core_t *core2, hal_rsa_key_t *
if (hal_modexp_using_modexpng()) {
if (blinding) {
+ DWT_start(DWT_create_blinding_factors);
if ((err = create_blinding_factors(key, bf, ubf)) != HAL_OK)
return err;
- return modexpng(core1, msg, key, bf, ubf, sig);
+ DWT_stop(DWT_create_blinding_factors);
+ DWT_start(DWT_modexpng);
+ err = modexpng(core1, msg, key, bf, ubf, sig);
+ DWT_stop(DWT_modexpng);
+ return err;
}
else {
- return modexpng(core1, msg, key, NULL, NULL, sig);
+ DWT_start(DWT_modexpng);
+ err = modexpng(core1, msg, key, NULL, NULL, sig);
+ DWT_stop(DWT_modexpng);
+ return err;
}
}
@@ -714,20 +766,26 @@ static hal_error_t rsa_crt(hal_core_t *core1, hal_core_t *core2, hal_rsa_key_t *
* Handle blinding if requested.
*/
if (blinding) {
+ DWT_start(DWT_create_blinding_factors);
if ((err = create_blinding_factors(key, bf, ubf)) != HAL_OK)
goto fail;
+ DWT_stop(DWT_create_blinding_factors);
/* msg = (msg * bf) % modulus */
+ DWT_start(DWT_blind_message);
FP_CHECK(fp_mulmod(msg, bf, unconst_fp_int(key->n), msg));
+ DWT_stop(DWT_blind_message);
}
/*
* m1 = msg ** dP mod p
* m2 = msg ** dQ mod q
*/
+ DWT_start(DWT_modexp2);
if ((err = modexp2(precalc, msg,
core1, key->dP, key->p, m1, key->pC, sizeof(key->pC), key->pF, sizeof(key->pF),
core2, key->dQ, key->q, m2, key->qC, sizeof(key->qC), key->qF, sizeof(key->qF))) != HAL_OK)
goto fail;
+ DWT_stop(DWT_modexp2);
if (precalc)
key->flags |= RSA_FLAG_PRECALC_PQ_DONE | RSA_FLAG_NEEDS_SAVING;
@@ -759,8 +817,11 @@ static hal_error_t rsa_crt(hal_core_t *core1, hal_core_t *core2, hal_rsa_key_t *
* Unblind if necessary.
*/
/* sig = (sig * ubf) % modulus */
- if (blinding)
+ if (blinding) {
+ DWT_restart(DWT_blind_message);
FP_CHECK(fp_mulmod(sig, ubf, unconst_fp_int(key->n), sig));
+ DWT_stop(DWT_blind_message);
+ }
fail:
fp_zero(t);
@@ -833,14 +894,19 @@ hal_error_t hal_rsa_decrypt(hal_core_t *core1,
* not sure what the point is.
*/
if (do_crt && !fp_iszero(key->p) && !fp_iszero(key->q) && !fp_iszero(key->u) &&
- !fp_iszero(key->dP) && !fp_iszero(key->dQ))
+ !fp_iszero(key->dP) && !fp_iszero(key->dQ)) {
+ DWT_start(DWT_rsa_crt);
err = rsa_crt(core1, core2, key, i, o);
+ DWT_stop(DWT_rsa_crt);
+ }
else {
const int precalc = !(key->flags & RSA_FLAG_PRECALC_N_DONE);
/* o = i ** d % n */
+ DWT_start(DWT_modexp);
err = modexp(core1, precalc, i, key->d, key->n, o, key->nC, sizeof(key->nC),
key->nF, sizeof(key->nF));
+ DWT_stop(DWT_modexp);
if (err == HAL_OK && precalc)
key->flags |= RSA_FLAG_PRECALC_N_DONE | RSA_FLAG_NEEDS_SAVING;
}
@@ -1174,10 +1240,14 @@ hal_error_t hal_rsa_key_gen(hal_core_t *core,
#if 0
if (hal_modexp_using_modexpng()) {
- modexp_precalc(key->n, key->nC, sizeof(key->nC), key->nF, sizeof(key->nF));
- modexp_precalc(key->p, key->pC, sizeof(key->pC), key->pF, sizeof(key->pF));
- modexp_precalc(key->q, key->qC, sizeof(key->qC), key->qF, sizeof(key->qF));
+ DWT_start(DWT_precalc_n);
+ modexpng_precalc(key->n, key->nC, sizeof(key->nC), key->nF, sizeof(key->nF));
+ DWT_stop(DWT_precalc_n);
+ DWT_start(DWT_precalc_pq);
+ modexpng_precalc(key->p, key->pC, sizeof(key->pC), key->pF, sizeof(key->pF));
+ modexpng_precalc(key->q, key->qC, sizeof(key->qC), key->qF, sizeof(key->qF));
key->flags |= RSA_FLAG_PRECALC_N_DONE | RSA_FLAG_PRECALC_PQ_DONE;
+ DWT_stop(DWT_precalc_pq);
}
#endif