From eda207f0a3d571a774039d772bff40131ff218d6 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Tue, 18 Feb 2020 19:36:58 -0500 Subject: timing tests for RSA signing --- core.c | 10 ++-- hal.h | 10 +++- ks.c | 24 ++++++-- modexp.c | 24 ++++++-- rpc_pkey.c | 68 ++++++++++++++++++---- rsa.c | 164 +++++++++++++++++++++++++++++++++++++--------------- verilog_constants.h | 8 ++- 7 files changed, 230 insertions(+), 78 deletions(-) diff --git a/core.c b/core.c index ed681dc..449b171 100644 --- a/core.c +++ b/core.c @@ -4,7 +4,9 @@ * This module contains code to probe the FPGA for its installed cores. * * Author: Paul Selkirk, Rob Austein - * Copyright (c) 2015-2017, 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 @@ -16,9 +18,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 diff --git a/hal.h b/hal.h index f01e47d..2bf97a6 100644 --- a/hal.h +++ b/hal.h @@ -5,6 +5,8 @@ * * Authors: Joachim Strombergson, Paul Selkirk, Rob Austein * Copyright (c) 2015-2017, NORDUnet A/S All rights reserved. + * Copyright: 2019-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 @@ -16,9 +18,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 @@ -499,6 +501,8 @@ extern void hal_rsa_set_debug(const int onoff); extern void hal_rsa_set_blinding(const int onoff); +extern void hal_rsa_clear_blinding_cache(void); + extern void hal_rsa_set_crt(const int onoff); extern hal_error_t hal_rsa_key_load_private(hal_rsa_key_t **key, diff --git a/ks.c b/ks.c index a682cd2..0e6b4ec 100644 --- a/ks.c +++ b/ks.c @@ -3,7 +3,9 @@ * ---- * Keystore, generic parts anyway. This is internal within libhal. * - * Copyright (c) 2015-2017, 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 @@ -15,9 +17,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 @@ -39,6 +41,13 @@ #include "hal_internal.h" #include "ks.h" +#ifdef DO_TIMING +#include "stm-dwt.h" +#else +#define DWT_start(x) +#define DWT_stop(x) +#endif + /* * PIN block gets the all-zeros UUID, which will never be returned by * the UUID generation code (by definition -- it's not a version 4 UUID). @@ -667,8 +676,13 @@ hal_error_t hal_ks_fetch(hal_ks_t *ks, *der_len = der_max; - if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) + DWT_start(DWT_hal_mkm_get_kek); + if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) { + DWT_stop(DWT_hal_mkm_get_kek); + DWT_start(DWT_hal_aes_keyunwrap); err = hal_aes_keyunwrap(NULL, kek, kek_len, der, k_der_len, der, der_len); + DWT_stop(DWT_hal_aes_keyunwrap); + } memset(kek, 0, sizeof(kek)); } diff --git a/modexp.c b/modexp.c index 85b43f5..8c026df 100644 --- a/modexp.c +++ b/modexp.c @@ -11,8 +11,9 @@ * enough that this module is no longer needed, it will go away. * * Authors: Rob Austein - * Copyright (c) 2015-2017, NORDUnet A/S - * All rights reserved. + * Copyright (c) 2015-2017, 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 @@ -24,9 +25,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 @@ -47,6 +48,13 @@ #include "hal.h" #include "hal_internal.h" +#ifdef DO_TIMING +#include "stm-dwt.h" +#else +#define DWT_start(x) HAL_OK +#define DWT_stop(x) HAL_OK +#endif + /* * Whether we want to use the new ModExpNG core. */ @@ -267,7 +275,7 @@ static inline hal_error_t setup_calc(const int precalc, hal_modexp_arg_t *a) if ((precalc && (err = get_buffer(a->core, MODEXPA7_ADDR_MODULUS_COEFF_OUT, a->coeff, a->coeff_len)) != HAL_OK) || (precalc && - (err = get_buffer(a->core, MODEXPA7_ADDR_MONTGOMERY_FACTOR_OUT, a->mont, a->mont_len)) != HAL_OK) || + (err = get_buffer(a->core, MODEXPA7_ADDR_MONTGOMERY_FACTOR_OUT, a->mont, a->mont_len)) != HAL_OK) || (err = set_buffer(a->core, MODEXPA7_ADDR_MODULUS_COEFF_IN, a->coeff, a->coeff_len)) != HAL_OK || (err = set_buffer(a->core, MODEXPA7_ADDR_MONTGOMERY_FACTOR_IN, a->mont, a->mont_len)) != HAL_OK || (err = set_register(a->core, MODEXPA7_ADDR_MODE, mode)) != HAL_OK || @@ -305,9 +313,11 @@ hal_error_t hal_modexp(const int precalc, hal_modexp_arg_t *a) if ((!free_core || (err = hal_core_alloc(MODEXPA7_NAME, &a->core, NULL)) == HAL_OK) && + (err = DWT_start(DWT_precalc_n)) == HAL_OK && (err = setup_precalc(precalc, a)) == HAL_OK && (!precalc || (err = hal_io_wait_ready(a->core)) == HAL_OK) && + (err = DWT_stop(DWT_precalc_n)) == HAL_OK && (err = setup_calc(precalc, a)) == HAL_OK && (err = hal_io_wait_valid(a->core)) == HAL_OK && (err = extract_result(a)) == HAL_OK) @@ -342,10 +352,12 @@ hal_error_t hal_modexp2(const int precalc, hal_modexp_arg_t *a1, hal_modexp_arg_ if ((!free_core || (err = hal_core_alloc2(MODEXPA7_NAME, &a1->core, NULL, MODEXPA7_NAME, &a2->core, NULL)) == HAL_OK) && + (err = DWT_start(DWT_precalc_pq)) == HAL_OK && (err = setup_precalc(precalc, a1)) == HAL_OK && (err = setup_precalc(precalc, a2)) == HAL_OK && (!precalc || (err = hal_io_wait_ready2(a1->core, a2->core)) == HAL_OK) && + (err = DWT_stop(DWT_precalc_pq)) == HAL_OK && (err = setup_calc(precalc, a1)) == HAL_OK && (err = setup_calc(precalc, a2)) == HAL_OK && (err = hal_io_wait_valid2(a1->core, a2->core)) == HAL_OK && diff --git a/rpc_pkey.c b/rpc_pkey.c index b44eb54..630bf93 100644 --- a/rpc_pkey.c +++ b/rpc_pkey.c @@ -3,8 +3,10 @@ * ---------- * Remote procedure call server-side public key implementation. * - * Authors: Rob Austein - * Copyright (c) 2015, NORDUnet A/S All rights reserved. + * Authors: Rob Austein, Paul Selkirk + * Copyright (c) 2015-2018, NORDUnet A/S All rights reserved. + * Copyright: 2019-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 @@ -16,9 +18,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 @@ -47,6 +49,13 @@ static hal_pkey_slot_t pkey_slot[HAL_STATIC_PKEY_STATE_BLOCKS]; #endif +#ifdef DO_TIMING +#include "stm-dwt.h" +#else +#define DWT_start(x) +#define DWT_stop(x) +#endif + /* * Handle allocation is simple: look for an unused (HAL_HANDLE_NONE) * slot in the table, and, assuming we find one, construct a composite @@ -445,6 +454,9 @@ static hal_error_t pkey_local_generate_rsa(const hal_client_handle_t client, uint8_t der[hal_rsa_private_key_to_der_len(key)]; size_t der_len; +#if 0 + printf("pkey_local_generate_rsa: key_len = %u, der_len = %u\n", key_length, sizeof(der)); +#endif if ((err = hal_rsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK) err = hal_ks_store(ks_from_flags(flags), slot, der, der_len); @@ -503,6 +515,9 @@ static hal_error_t pkey_local_generate_ec(const hal_client_handle_t client, uint8_t der[hal_ecdsa_private_key_to_der_len(key)]; size_t der_len; +#if 0 + printf("pkey_local_generate_ec: curve = %u, der_len = %u\n", curve, sizeof(der)); +#endif if ((err = hal_ecdsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK) err = hal_ks_store(ks_from_flags(flags), slot, der, der_len); @@ -562,6 +577,9 @@ static hal_error_t pkey_local_generate_hashsig(const hal_client_handle_t client, uint8_t der[hal_hashsig_private_key_to_der_len(key)]; size_t der_len; +#if 0 + printf("pkey_local_generate_hashsig: hss = %u, lms = %u, lmots = %u, der_len = %u\n", hss_levels, lms_type, lmots_type, sizeof(der)); +#endif if ((err = hal_hashsig_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK) err = hal_ks_store(ks_from_flags(flags), slot, der, der_len); @@ -798,7 +816,10 @@ static hal_error_t pkey_local_sign_rsa(hal_pkey_slot_t *slot, hal_assert(signature != NULL && signature_len != NULL); hal_assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0)); - if ((err = hal_rsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len)) != HAL_OK || + DWT_start(DWT_hal_rsa_private_key_from_der); + err = hal_rsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len); + DWT_stop(DWT_hal_rsa_private_key_from_der); + if (err != HAL_OK || (err = hal_rsa_key_get_modulus(key, NULL, signature_len, 0)) != HAL_OK) return err; @@ -811,15 +832,30 @@ static hal_error_t pkey_local_sign_rsa(hal_pkey_slot_t *slot, input = signature; } - if ((err = pkcs1_5_pad(input, input_len, signature, *signature_len, 0x01)) != HAL_OK || - (err = hal_rsa_decrypt(NULL, NULL, key, signature, *signature_len, signature, *signature_len)) != HAL_OK) + if ((err = pkcs1_5_pad(input, input_len, signature, *signature_len, 0x01)) != HAL_OK) + return err; + DWT_start(DWT_hal_rsa_decrypt); + err = hal_rsa_decrypt(NULL, NULL, key, signature, *signature_len, signature, *signature_len); + DWT_stop(DWT_hal_rsa_decrypt); + if (err != HAL_OK) return err; if (hal_rsa_key_needs_saving(key)) { uint8_t pkcs8[hal_rsa_private_key_to_der_extra_len(key)]; size_t pkcs8_len = 0; +#if 0 + printf("pkey_local_sign_rsa: der_len = %u\n", sizeof(pkcs8)); +#endif if ((err = hal_rsa_private_key_to_der_extra(key, pkcs8, &pkcs8_len, sizeof(pkcs8))) == HAL_OK) err = hal_ks_rewrite_der(ks_from_flags(slot->flags), slot, pkcs8, pkcs8_len); +#if 0 + size_t i; + for (i = 0; i < sizeof(pkcs8); ++i) { + printf("%02x%c", pkcs8[i], (i & 0x0f) == 0x0f ? '\n' : ' '); + } + if (i & 0x0f) + printf("\n"); +#endif memset(pkcs8, 0, sizeof(pkcs8)); if (err != HAL_OK) return err; @@ -951,9 +987,15 @@ static hal_error_t pkey_local_sign(const hal_pkey_handle_t pkey, size_t der_len; hal_error_t err; - if ((err = ks_fetch_from_flags(slot, der, &der_len, sizeof(der))) == HAL_OK) + DWT_start(DWT_hal_ks_fetch); + err = ks_fetch_from_flags(slot, der, &der_len, sizeof(der)); + DWT_stop(DWT_hal_ks_fetch); + if (err == HAL_OK) { + DWT_start(DWT_pkey_local_sign_rsa); err = signer(slot, keybuf, sizeof(keybuf), der, der_len, hash, input, input_len, signature, signature_len, signature_max); + DWT_stop(DWT_pkey_local_sign_rsa); + } memset(keybuf, 0, sizeof(keybuf)); memset(der, 0, sizeof(der)); @@ -1225,6 +1267,7 @@ static hal_error_t pkey_local_match(const hal_client_handle_t client, case MATCH_STATE_START: prev = uuid_zero; ++*state; + /* fall through */ case MATCH_STATE_TOKEN: if (((mask & HAL_KEY_FLAG_TOKEN) == 0 || (mask & flags & HAL_KEY_FLAG_TOKEN) != 0) && @@ -1236,6 +1279,7 @@ static hal_error_t pkey_local_match(const hal_client_handle_t client, return HAL_OK; prev = uuid_zero; ++*state; + /* fall through */ case MATCH_STATE_VOLATILE: if (((mask & HAL_KEY_FLAG_TOKEN) == 0 || (mask & flags & HAL_KEY_FLAG_TOKEN) == 0) && @@ -1246,6 +1290,7 @@ static hal_error_t pkey_local_match(const hal_client_handle_t client, if (*result_len == result_max) return HAL_OK; ++*state; + /* fall through */ case MATCH_STATE_DONE: return HAL_OK; @@ -1431,7 +1476,10 @@ static hal_error_t pkey_local_import(const hal_client_handle_t client, goto fail; } - if ((err = hal_rsa_decrypt(NULL, NULL, rsa, data, data_len, der, data_len)) != HAL_OK) + DWT_start(DWT_hal_rsa_decrypt); + err = hal_rsa_decrypt(NULL, NULL, rsa, data, data_len, der, data_len); + DWT_stop(DWT_hal_rsa_decrypt); + if (err != HAL_OK) goto fail; if ((err = hal_get_random(NULL, kek, sizeof(kek))) != HAL_OK) 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 #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 diff --git a/verilog_constants.h b/verilog_constants.h index f92adaa..bd31ee3 100644 --- a/verilog_constants.h +++ b/verilog_constants.h @@ -9,6 +9,8 @@ * * Authors: Joachim Strombergson, Paul Selkirk, Rob Austein * Copyright (c) 2015-2017, 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 @@ -20,9 +22,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 -- cgit v1.2.3