aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aes_keywrap.c19
-rw-r--r--asn1.c21
-rw-r--r--core.c233
-rwxr-xr-xcryptech_muxd12
-rw-r--r--csprng.c8
-rw-r--r--ecdsa.c71
-rw-r--r--hal.h31
-rw-r--r--hal_internal.h26
-rw-r--r--hal_io_fmc.c35
-rw-r--r--hash.c232
-rw-r--r--ks.c19
-rw-r--r--ks_attribute.c1
-rw-r--r--ks_token.c1
-rw-r--r--ks_volatile.c1
-rw-r--r--locks.c31
-rw-r--r--mkmif.c38
-rw-r--r--modexp.c57
-rw-r--r--pbkdf2.c9
-rw-r--r--rpc_client.c8
-rw-r--r--rpc_pkcs1.c8
-rw-r--r--rpc_pkey.c55
-rw-r--r--rpc_serial.c2
-rw-r--r--rsa.c147
-rw-r--r--slip.c2
-rwxr-xr-xtests/parallel-signatures.py57
-rw-r--r--tests/test-rsa.c41
-rw-r--r--uuid.c1
27 files changed, 660 insertions, 506 deletions
diff --git a/aes_keywrap.c b/aes_keywrap.c
index 355cb0b..144ad68 100644
--- a/aes_keywrap.c
+++ b/aes_keywrap.c
@@ -45,7 +45,6 @@
#include <stdint.h>
#include <string.h>
-#include <assert.h>
#include "hal.h"
#include "hal_internal.h"
@@ -132,7 +131,7 @@ static hal_error_t do_block(const hal_core_t *core, uint8_t *b1, uint8_t *b2)
{
hal_error_t err;
- assert(b1 != NULL && b2 != NULL);
+ hal_assert(b1 != NULL && b2 != NULL);
if ((err = hal_io_write(core, AES_ADDR_BLOCK0, b1, 8)) != HAL_OK ||
(err = hal_io_write(core, AES_ADDR_BLOCK2, b2, 8)) != HAL_OK ||
@@ -164,15 +163,16 @@ hal_error_t hal_aes_keywrap(hal_core_t *core,
size_t *C_len)
{
const size_t calculated_C_len = hal_aes_keywrap_ciphertext_length(m);
+ const int free_core = core == NULL;
hal_error_t err;
size_t n;
- assert(calculated_C_len % 8 == 0);
+ hal_assert(calculated_C_len % 8 == 0);
if (Q == NULL || C == NULL || C_len == NULL || *C_len < calculated_C_len)
return HAL_ERROR_BAD_ARGUMENTS;
- if ((err = hal_core_alloc(AES_CORE_NAME, &core)) != HAL_OK)
+ if (free_core && (err = hal_core_alloc(AES_CORE_NAME, &core, NULL)) != HAL_OK)
return err;
if ((err = load_kek(core, K, K_len, KEK_encrypting)) != HAL_OK)
@@ -215,7 +215,8 @@ hal_error_t hal_aes_keywrap(hal_core_t *core,
}
out:
- hal_core_free(core);
+ if (free_core)
+ hal_core_free(core);
return err;
}
@@ -226,13 +227,14 @@ out:
* Q should be the same size as C. Q and C can overlap.
*/
-hal_error_t hal_aes_keyunwrap(hal_core_t * core,
+hal_error_t hal_aes_keyunwrap(hal_core_t *core,
const uint8_t *K, const size_t K_len,
const uint8_t * const C,
const size_t C_len,
uint8_t *Q,
size_t *Q_len)
{
+ const int free_core = core == NULL;
hal_error_t err;
size_t n;
size_t m;
@@ -240,7 +242,7 @@ hal_error_t hal_aes_keyunwrap(hal_core_t * core,
if (C == NULL || Q == NULL || C_len % 8 != 0 || C_len < 16 || Q_len == NULL || *Q_len < C_len)
return HAL_ERROR_BAD_ARGUMENTS;
- if ((err = hal_core_alloc(AES_CORE_NAME, &core)) != HAL_OK)
+ if (free_core && (err = hal_core_alloc(AES_CORE_NAME, &core, NULL)) != HAL_OK)
return err;
if ((err = load_kek(core, K, K_len, KEK_decrypting)) != HAL_OK)
@@ -294,7 +296,8 @@ hal_error_t hal_aes_keyunwrap(hal_core_t * core,
memmove(Q, Q + 8, m);
out:
- hal_core_free(core);
+ if (free_core)
+ hal_core_free(core);
return err;
}
diff --git a/asn1.c b/asn1.c
index 1799ac9..d57ec96 100644
--- a/asn1.c
+++ b/asn1.c
@@ -49,7 +49,6 @@
*/
#include <stdint.h>
-#include <assert.h>
#include "hal.h"
#include "hal_internal.h"
@@ -197,7 +196,7 @@ hal_error_t hal_asn1_encode_integer(const fp_int * const bn,
if (der == NULL || err != HAL_OK)
return err;
- assert(hlen + vlen <= der_max);
+ hal_assert(hlen + vlen <= der_max);
der += hlen;
if (leading_zero)
@@ -240,7 +239,7 @@ hal_error_t hal_asn1_encode_uint32(const uint32_t n,
if (der == NULL || err != HAL_OK)
return err;
- assert(hlen + vlen <= der_max);
+ hal_assert(hlen + vlen <= der_max);
der += hlen;
@@ -276,7 +275,7 @@ hal_error_t hal_asn1_encode_octet_string(const uint8_t * const data, const si
if (der == NULL)
return HAL_OK;
- assert(hlen + data_len <= der_max);
+ hal_assert(hlen + data_len <= der_max);
/*
* Handle data early, in case it was staged into our output buffer.
@@ -365,8 +364,8 @@ hal_error_t hal_asn1_encode_spki(const uint8_t * const alg_oid, const size_t a
*d++ = 0x00;
d += pubkey_len; /* pubkey handled early, above. */
- assert(d == der + hlen_spki + vlen);
- assert(d <= der + der_max);
+ hal_assert(d == der + hlen_spki + vlen);
+ hal_assert(d <= der + der_max);
return HAL_OK;
}
@@ -457,8 +456,8 @@ hal_error_t hal_asn1_encode_pkcs8_privatekeyinfo(const uint8_t * const alg_oid,
d += hlen;
d += privkey_len; /* privkey handled early, above. */
- assert(d == der_end);
- assert(d <= der + der_max);
+ hal_assert(d == der_end);
+ hal_assert(d <= der + der_max);
return HAL_OK;
}
@@ -525,8 +524,8 @@ hal_error_t hal_asn1_encode_pkcs8_encryptedprivatekeyinfo(const uint8_t * const
d += data_len; /* data handled early, above. */
- assert(d == der + hlen_pkcs8 + vlen);
- assert(d <= der + der_max);
+ hal_assert(d == der + hlen_pkcs8 + vlen);
+ hal_assert(d <= der + der_max);
return HAL_OK;
}
@@ -542,7 +541,7 @@ hal_error_t hal_asn1_decode_header(const uint8_t tag,
const uint8_t * const der, size_t der_max,
size_t *hlen, size_t *vlen)
{
- assert(der != NULL && hlen != NULL && vlen != NULL);
+ hal_assert(der != NULL && hlen != NULL && vlen != NULL);
if (der_max < 2 || der[0] != tag)
return HAL_ERROR_ASN1_PARSE_FAILED;
diff --git a/core.c b/core.c
index c604a15..e170210 100644
--- a/core.c
+++ b/core.c
@@ -56,16 +56,15 @@ extern size_t strnlen(const char *, size_t);
struct hal_core {
hal_core_info_t info;
- uint32_t busy;
+ int busy;
+ hal_core_lru_t lru;
struct hal_core *next;
};
-#ifndef HAL_STATIC_CORE_STATE_BLOCKS
-#define HAL_STATIC_CORE_STATE_BLOCKS 0
-#endif
-
-#if HAL_STATIC_CORE_STATE_BLOCKS > 0
+#if defined(HAL_STATIC_CORE_STATE_BLOCKS) && HAL_STATIC_CORE_STATE_BLOCKS > 0
static hal_core_t core_table[HAL_STATIC_CORE_STATE_BLOCKS];
+#else
+#error HAL_STATIC_CORE_STATE_BLOCKS must be defined as a positive integer
#endif
/*
@@ -73,7 +72,7 @@ static hal_core_t core_table[HAL_STATIC_CORE_STATE_BLOCKS];
* bit nasty due to non-null-terminated fixed-length names.
*/
-static int name_matches(const hal_core_t *const core, const char * const name)
+static inline int name_matches(const hal_core_t *const core, const char * const name)
{
return (core != NULL && name != NULL && *name != '\0' &&
strncmp(name, core->info.name, strnlen(name, sizeof(core->info.name))) == 0);
@@ -92,39 +91,34 @@ static int name_matches(const hal_core_t *const core, const char * const name)
#define CORE_MAX 0x10000
#define CORE_SIZE 0x100
-/* Extra space to leave after particular cores. Yummy. */
-
-static const struct { const char *name; hal_addr_t extra; } gaps[] = {
- { "csprng", 11 * CORE_SIZE }, /* empty slots after csprng */
- { "modexps6", 3 * CORE_SIZE }, /* ModexpS6 uses four slots */
- { "modexpa7", 7 * CORE_SIZE }, /* ModexpA7 uses eight slots */
-};
-
static hal_core_t *head = NULL;
+static hal_core_lru_t lru = 0;
-static hal_core_t *probe_cores(void)
+static inline hal_core_t *probe_cores(void)
{
+ /* Extra space to leave after particular cores. Yummy. */
+ static const struct { const char *name; hal_addr_t extra; } gaps[] = {
+ { "csprng", 11 * CORE_SIZE }, /* empty slots after csprng */
+ { "modexps6", 3 * CORE_SIZE }, /* ModexpS6 uses four slots */
+ { "modexpa7", 7 * CORE_SIZE }, /* ModexpA7 uses eight slots */
+ };
+
+ if (offsetof(hal_core_t, info) != 0)
+ return NULL; /* Paranoia, see hal.h */
+
if (head != NULL)
return head;
- hal_core_t *core = NULL;
hal_core_t **tail = &head;
hal_error_t err = HAL_OK;
-#if HAL_STATIC_CORE_STATE_BLOCKS > 0
- int n = 0;
-#endif
+ hal_addr_t addr;
+ int n;
- for (hal_addr_t addr = CORE_MIN; addr < CORE_MAX; addr += CORE_SIZE) {
-
-#if HAL_STATIC_CORE_STATE_BLOCKS > 0
- core = &core_table[n];
-#else
- if (core == NULL && (core = malloc(sizeof(hal_core_t))) == NULL) {
- err = HAL_ERROR_ALLOCATION_FAILURE;
- goto fail;
- }
-#endif
+ for (addr = CORE_MIN, n = 0;
+ addr < CORE_MAX && n < HAL_STATIC_CORE_STATE_BLOCKS;
+ addr += CORE_SIZE, n++) {
+ hal_core_t *core = &core_table[n];
memset(core, 0, sizeof(*core));
core->info.base = addr;
@@ -144,48 +138,19 @@ static hal_core_t *probe_cores(void)
*tail = core;
tail = &core->next;
- core = NULL;
-
-#if HAL_STATIC_CORE_STATE_BLOCKS > 0
- if (++n >= HAL_STATIC_CORE_STATE_BLOCKS)
- break;
-#endif
}
-#if HAL_STATIC_CORE_STATE_BLOCKS > 0
-#else
- if (core != NULL)
- free(core);
-#endif
-
return head;
fail:
-#if HAL_STATIC_CORE_STATE_BLOCKS > 0
memset(core_table, 0, sizeof(core_table));
-#else
- if (core != NULL)
- free(core);
- while ((core = head) != NULL) {
- head = core->next;
- free(core);
- }
-#endif
return NULL;
}
void hal_core_reset_table(void)
{
-#if HAL_STATIC_CORE_STATE_BLOCKS > 0
- head = NULL;
- memset(core_table, 0, sizeof(core_table));
-#else
- while (head != NULL) {
- hal_core_t *next = head->next;
- free(head);
- head = next;
- }
-#endif
+ head = NULL;
+ memset(core_table, 0, sizeof(core_table));
}
hal_core_t * hal_core_iterate(hal_core_t *core)
@@ -201,76 +166,133 @@ hal_core_t *hal_core_find(const char *name, hal_core_t *core)
return NULL;
}
-static hal_error_t hal_core_alloc_no_wait(const char *name, hal_core_t **pcore)
-{
- /*
- * This used to allow name == NULL iff *core != NULL, but the
- * semantics were fragile and in practice we always pass a name
- * anyway, so simplify by requiring name != NULL, always.
- */
+/*
+ * If caller specifies a non-NULL core value, we fail unless that core
+ * is available and has the right name and lru values.
+ *
+ * If caller specifies a NULL core value, we take any free core with
+ * the right name.
+ *
+ * Modification of lru field is handled by the jacket routines, to
+ * avoid premature updates.
+ */
- if (name == NULL || pcore == NULL)
+static hal_error_t hal_core_alloc_no_wait(const char *name, hal_core_t **pcore, hal_core_lru_t *pomace)
+{
+ if (name == NULL || pcore == NULL || (*pcore != NULL && pomace == NULL))
return HAL_ERROR_BAD_ARGUMENTS;
hal_error_t err = HAL_ERROR_CORE_NOT_FOUND;
hal_core_t *core = *pcore;
+ hal_core_t *best = NULL;
+ uint32_t age = 0;
+
+ hal_critical_section_start();
+ /*
+ * User wants to reuse previous core, grab that core or or bust.
+ * Never return CORE_BUSY in this case, because busy implies
+ * somebody else has touched it. Checking the name in this case
+ * isn't strictly necessary, but it's cheap insurance.
+ */
if (core != NULL) {
- /* if we can reallocate the same core, do it now */
- if (!core->busy) {
- hal_critical_section_start();
+ if (core->busy || core->lru != *pomace)
+ err = HAL_ERROR_CORE_REASSIGNED;
+ else if (!name_matches(core, name))
+ err = HAL_ERROR_CORE_NOT_FOUND;
+ else {
core->busy = 1;
- hal_critical_section_end();
- return HAL_OK;
+ err = HAL_OK;
}
- /* else forget that core and fall through to search */
- *pcore = NULL;
}
- hal_critical_section_start();
- for (core = hal_core_find(name, NULL); core != NULL; core = hal_core_find(name, core)) {
- if (core->busy) {
- err = HAL_ERROR_CORE_BUSY;
- continue;
+ /*
+ * User just wants a core with the right name, search for least recently used matching core.
+ */
+ else {
+ for (core = hal_core_find(name, NULL); core != NULL; core = hal_core_find(name, core)) {
+ if (core->busy && err == HAL_ERROR_CORE_NOT_FOUND) {
+ err = HAL_ERROR_CORE_BUSY;
+ }
+ else if (!core->busy && (lru - core->lru) >= age) {
+ best = core;
+ age = (lru - core->lru);
+ }
+ }
+ if (best != NULL) {
+ *pcore = best;
+ best->busy = 1;
+ err = HAL_OK;
}
- err = HAL_OK;
- *pcore = core;
- core->busy = 1;
- break;
}
+
hal_critical_section_end();
return err;
}
-hal_error_t hal_core_alloc(const char *name, hal_core_t **pcore)
+hal_error_t hal_core_alloc(const char *name, hal_core_t **pcore, hal_core_lru_t *pomace)
{
hal_error_t err;
- while ((err = hal_core_alloc_no_wait(name, pcore)) == HAL_ERROR_CORE_BUSY)
+ while ((err = hal_core_alloc_no_wait(name, pcore, pomace)) == HAL_ERROR_CORE_BUSY)
hal_task_yield();
- return err;
+ if (err != HAL_OK)
+ return err;
+
+ (*pcore)->lru = ++lru;
+
+ if (pomace != NULL)
+ *pomace = (*pcore)->lru;
+
+ return HAL_OK;
}
-hal_error_t hal_core_alloc2(const char *name1, hal_core_t **pcore1,
- const char *name2, hal_core_t **pcore2)
+hal_error_t hal_core_alloc2(const char *name1, hal_core_t **pcore1, hal_core_lru_t *pomace1,
+ const char *name2, hal_core_t **pcore2, hal_core_lru_t *pomace2)
{
- hal_error_t err;
+ const int clear = pcore1 != NULL && *pcore1 == NULL;
+
+ for (;;) {
+
+ hal_error_t err = hal_core_alloc_no_wait(name1, pcore1, pomace1);
+
+ switch (err) {
+
+ case HAL_OK:
+ break;
- while (1) {
- if ((err = hal_core_alloc(name1, pcore1)) != HAL_OK)
+ case HAL_ERROR_CORE_BUSY:
+ hal_task_yield();
+ continue;
+
+ default:
return err;
+ }
+
+ if ((err = hal_core_alloc_no_wait(name2, pcore2, pomace2)) == HAL_OK)
+ break;
- if ((err = hal_core_alloc_no_wait(name2, pcore2)) == HAL_OK)
- return HAL_OK;
-
- hal_core_free(*pcore1);
- /* hal_core_free does a yield, so we don't need to do another one */
+ hal_core_free(*pcore1); /* hal_core_free does a yield, so we don't need to do another one */
+
+ if (clear) /* put *pcore1 back as we found it */
+ *pcore1 = NULL;
if (err != HAL_ERROR_CORE_BUSY)
return err;
}
+
+ (*pcore1)->lru = ++lru;
+ (*pcore2)->lru = ++lru;
+
+ if (pomace1 != NULL)
+ *pomace1 = (*pcore1)->lru;
+
+ if (pomace2 != NULL)
+ *pomace2 = (*pcore2)->lru;
+
+ return HAL_OK;
}
void hal_core_free(hal_core_t *core)
@@ -283,21 +305,6 @@ void hal_core_free(hal_core_t *core)
}
}
-hal_addr_t hal_core_base(const hal_core_t *core)
-{
- return core == NULL ? 0 : core->info.base;
-}
-
-const hal_core_info_t *hal_core_info(const hal_core_t *core)
-{
- return core == NULL ? NULL : &core->info;
-}
-
-int hal_core_busy(const hal_core_t *core)
-{
- return (int)core->busy;
-}
-
/*
* Local variables:
* indent-tabs-mode: nil
diff --git a/cryptech_muxd b/cryptech_muxd
index d306eaf..1aecb1e 100755
--- a/cryptech_muxd
+++ b/cryptech_muxd
@@ -419,6 +419,10 @@ def main():
default = os.getenv("CRYPTECH_RPC_CLIENT_SOCKET_NAME",
"/tmp/.cryptech_muxd.rpc"))
+ parser.add_argument("--rpc-socket-mode",
+ help = "permission bits for RPC socket inode",
+ default = 0600, type = lambda s: int(s, 8))
+
parser.add_argument("--cty-device",
help = "CTY serial device name",
default = os.getenv("CRYPTECH_CTY_CLIENT_SERIAL_DEVICE"))
@@ -428,6 +432,10 @@ def main():
default = os.getenv("CRYPTECH_CTY_CLIENT_SOCKET_NAME",
"/tmp/.cryptech_muxd.cty"))
+ parser.add_argument("--cty-socket-mode",
+ help = "permission bits for CTY socket inode",
+ default = 0600, type = lambda s: int(s, 8))
+
args = parser.parse_args()
if args.log_file is not None:
@@ -454,7 +462,7 @@ def main():
logger.warn("No RPC device found")
else:
rpc_stream = RPCIOStream(device = args.rpc_device)
- rpc_server = RPCServer(rpc_stream, args.rpc_socket)
+ rpc_server = RPCServer(rpc_stream, args.rpc_socket, args.rpc_socket_mode)
futures.append(rpc_stream.rpc_output_loop())
futures.append(rpc_stream.logout_all())
@@ -462,7 +470,7 @@ def main():
logger.warn("No CTY device found")
else:
cty_stream = CTYIOStream(device = args.cty_device, console_log = console_log)
- cty_server = CTYServer(cty_stream, args.cty_socket)
+ cty_server = CTYServer(cty_stream, args.cty_socket, args.cty_socket_mode)
futures.append(cty_stream.cty_output_loop())
# Might want to use WaitIterator(dict(...)) here so we can
diff --git a/csprng.c b/csprng.c
index 8ba4fa5..a760100 100644
--- a/csprng.c
+++ b/csprng.c
@@ -46,9 +46,10 @@
hal_error_t hal_get_random(hal_core_t *core, void *buffer, const size_t length)
{
uint8_t temp[4], ior = 0, * const buf = buffer;
- hal_error_t err;
+ const int free_core = core == NULL;
+ hal_error_t err = HAL_OK;
- if ((err = hal_core_alloc(CSPRNG_NAME, &core)) != HAL_OK)
+ if (free_core && (err = hal_core_alloc(CSPRNG_NAME, &core, NULL)) != HAL_OK)
return err;
for (size_t i = 0; i < length; i += 4) {
@@ -73,7 +74,8 @@ hal_error_t hal_get_random(hal_core_t *core, void *buffer, const size_t length)
err = HAL_ERROR_CSPRNG_BROKEN;
}
- hal_core_free(core);
+ if (free_core)
+ hal_core_free(core);
return err;
}
diff --git a/ecdsa.c b/ecdsa.c
index d1b8d0c..5991d21 100644
--- a/ecdsa.c
+++ b/ecdsa.c
@@ -68,7 +68,6 @@
*/
#include <stdint.h>
-#include <assert.h>
#include "hal.h"
#include "hal_internal.h"
@@ -354,8 +353,7 @@ static inline void ff_sqr(const ecdsa_curve_t * const curve,
static inline int point_is_infinite(const ec_point_t * const P)
{
- assert(P != NULL);
- return fp_iszero(P->z);
+ return P == NULL || fp_iszero(P->z);
}
/*
@@ -367,9 +365,9 @@ static inline int point_is_infinite(const ec_point_t * const P)
* infinity for that curve.
*/
-static inline void point_set_infinite(ec_point_t *P, const ecdsa_curve_t * const curve)
+static inline hal_error_t point_set_infinite(ec_point_t *P, const ecdsa_curve_t * const curve)
{
- assert(P != NULL);
+ hal_assert(P != NULL);
if (curve != NULL) {
fp_copy(unconst_fp_int(curve->mu), P->x);
@@ -382,6 +380,8 @@ static inline void point_set_infinite(ec_point_t *P, const ecdsa_curve_t * const
fp_set(P->y, 1);
fp_zero(P->z);
}
+
+ return HAL_OK;
}
/*
@@ -403,7 +403,7 @@ static inline void point_copy(const ec_point_t * const P, ec_point_t *R)
static inline hal_error_t point_to_montgomery(ec_point_t *P,
const ecdsa_curve_t * const curve)
{
- assert(P != NULL && curve != NULL);
+ hal_assert(P != NULL && curve != NULL);
if (fp_cmp_d(unconst_fp_int(P->z), 1) != FP_EQ)
return HAL_ERROR_BAD_ARGUMENTS;
@@ -431,7 +431,7 @@ static inline hal_error_t point_to_montgomery(ec_point_t *P,
static inline hal_error_t point_to_affine(ec_point_t *P,
const ecdsa_curve_t * const curve)
{
- assert(P != NULL && curve != NULL);
+ hal_assert(P != NULL && curve != NULL);
if (point_is_infinite(P))
return HAL_ERROR_IMPOSSIBLE;
@@ -475,11 +475,11 @@ static inline hal_error_t point_to_affine(ec_point_t *P,
* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
*/
-static inline void point_double(const ec_point_t * const P,
- ec_point_t *R,
- const ecdsa_curve_t * const curve)
+static inline hal_error_t point_double(const ec_point_t * const P,
+ ec_point_t *R,
+ const ecdsa_curve_t * const curve)
{
- assert(P != NULL && R != NULL && curve != NULL);
+ hal_assert(P != NULL && R != NULL && curve != NULL);
const int was_infinite = point_is_infinite(P);
@@ -520,9 +520,11 @@ static inline void point_double(const ec_point_t * const P,
ff_add (curve, t2, t2, t2);
ff_sub (curve, t1, t2, R->y);
- assert(was_infinite == point_is_infinite(P));
+ hal_assert(was_infinite == point_is_infinite(P));
fp_zero(alpha); fp_zero(beta); fp_zero(gamma); fp_zero(delta); fp_zero(t1); fp_zero(t2);
+
+ return HAL_OK;
}
/**
@@ -542,18 +544,18 @@ static inline void point_double(const ec_point_t * const P,
* point doubling algorithm.
*/
-static inline void point_add(const ec_point_t * const P,
- const ec_point_t * const Q,
- ec_point_t *R,
- const ecdsa_curve_t * const curve)
+static inline hal_error_t point_add(const ec_point_t * const P,
+ const ec_point_t * const Q,
+ ec_point_t *R,
+ const ecdsa_curve_t * const curve)
{
- assert(P != NULL && Q != NULL && R != NULL && curve != NULL);
+ hal_assert(P != NULL && Q != NULL && R != NULL && curve != NULL);
/*
* Q must be affine in Montgomery form.
*/
- assert(fp_cmp(unconst_fp_int(Q->z), unconst_fp_int(curve->mu)) == FP_EQ);
+ hal_assert(fp_cmp(unconst_fp_int(Q->z), unconst_fp_int(curve->mu)) == FP_EQ);
#warning What happens here if P and Q are not equal but map to the same point in affine space?
@@ -640,6 +642,8 @@ static inline void point_add(const ec_point_t * const P,
else if (result_is_infinite)
point_set_infinite(R, curve);
+
+ return HAL_OK;
}
/**
@@ -658,7 +662,7 @@ static hal_error_t point_scalar_multiply(const fp_int * const k,
ec_point_t *R,
const ecdsa_curve_t * const curve)
{
- assert(k != NULL && P_ != NULL && R != NULL && curve != NULL);
+ hal_assert(k != NULL && P_ != NULL && R != NULL && curve != NULL);
if (fp_iszero(k) || fp_cmp_d(unconst_fp_int(P_->z), 1) != FP_EQ)
return HAL_ERROR_BAD_ARGUMENTS;
@@ -787,7 +791,7 @@ static hal_error_t verilog_point_pick_random(const verilog_ecdsa_driver_t * cons
fp_int *k,
ec_point_t *P)
{
- assert(k != NULL && P != NULL);
+ hal_assert(k != NULL && P != NULL);
const size_t len = fp_unsigned_bin_size(k);
uint8_t b[driver->bytes];
@@ -798,7 +802,7 @@ static hal_error_t verilog_point_pick_random(const verilog_ecdsa_driver_t * cons
if (len > sizeof(b))
return HAL_ERROR_RESULT_TOO_LONG;
- if ((err = hal_core_alloc(driver->name, &core)) != HAL_OK)
+ if ((err = hal_core_alloc(driver->name, &core, NULL)) != HAL_OK)
goto fail;
#define check(_x_) do { if ((err = (_x_)) != HAL_OK) goto fail; } while (0)
@@ -846,7 +850,7 @@ static hal_error_t point_pick_random(const ecdsa_curve_t * const curve,
{
hal_error_t err;
- assert(curve != NULL && k != NULL && P != NULL);
+ hal_assert(curve != NULL && k != NULL && P != NULL);
/*
* Pick a random scalar corresponding to a point on the curve. Per
@@ -933,7 +937,8 @@ static hal_error_t point_pick_random(const ecdsa_curve_t * const curve,
static int point_is_on_curve(const ec_point_t * const P,
const ecdsa_curve_t * const curve)
{
- assert(P != NULL && curve != NULL);
+ if (P == NULL || curve == NULL)
+ return 0;
fp_int t1[1] = INIT_FP_INT;
fp_int t2[1] = INIT_FP_INT;
@@ -966,6 +971,8 @@ static int point_is_on_curve(const ec_point_t * const P,
return fp_cmp(t1, unconst_fp_int(curve->b)) == FP_EQ;
}
+#warning hal_ecdsa_xxx() functions currently ignore core arguments, works but suboptimal, fix this
+
/*
* Generate a new ECDSA key.
*/
@@ -1172,7 +1179,7 @@ hal_error_t hal_ecdsa_key_to_ecpoint(const hal_ecdsa_key_t * const key,
const size_t q_len = fp_unsigned_bin_size(unconst_fp_int(curve->q));
const size_t Qx_len = fp_unsigned_bin_size(unconst_fp_int(key->Q->x));
const size_t Qy_len = fp_unsigned_bin_size(unconst_fp_int(key->Q->y));
- assert(q_len >= Qx_len && q_len >= Qy_len);
+ hal_assert(q_len >= Qx_len && q_len >= Qy_len);
const size_t vlen = q_len * 2 + 1;
size_t hlen;
@@ -1185,7 +1192,7 @@ hal_error_t hal_ecdsa_key_to_ecpoint(const hal_ecdsa_key_t * const key,
if (der == NULL || err != HAL_OK)
return err;
- assert(hlen + vlen <= der_max);
+ hal_assert(hlen + vlen <= der_max);
uint8_t *d = der + hlen;
memset(d, 0, vlen);
@@ -1198,7 +1205,7 @@ hal_error_t hal_ecdsa_key_to_ecpoint(const hal_ecdsa_key_t * const key,
fp_to_unsigned_bin(unconst_fp_int(key->Q->y), d + q_len - Qy_len);
d += q_len;
- assert(d <= der + der_max);
+ hal_assert(d <= der + der_max);
return HAL_OK;
}
@@ -1291,7 +1298,7 @@ hal_error_t hal_ecdsa_private_key_to_der(const hal_ecdsa_key_t * const key,
const size_t d_len = fp_unsigned_bin_size(unconst_fp_int(key->d));
const size_t Qx_len = fp_unsigned_bin_size(unconst_fp_int(key->Q->x));
const size_t Qy_len = fp_unsigned_bin_size(unconst_fp_int(key->Q->y));
- assert(q_len >= d_len && q_len >= Qx_len && q_len >= Qy_len);
+ hal_assert(q_len >= d_len && q_len >= Qx_len && q_len >= Qy_len);
fp_int version[1] = INIT_FP_INT;
fp_set(version, 1);
@@ -1466,7 +1473,7 @@ hal_error_t hal_ecdsa_public_key_to_der(const hal_ecdsa_key_t * const key,
const size_t Qx_len = fp_unsigned_bin_size(unconst_fp_int(key->Q->x));
const size_t Qy_len = fp_unsigned_bin_size(unconst_fp_int(key->Q->y));
const size_t ecpoint_len = q_len * 2 + 1;
- assert(q_len >= Qx_len && q_len >= Qy_len);
+ hal_assert(q_len >= Qx_len && q_len >= Qy_len);
if (der != NULL && ecpoint_len < der_max) {
memset(der, 0, ecpoint_len);
@@ -1480,7 +1487,7 @@ hal_error_t hal_ecdsa_public_key_to_der(const hal_ecdsa_key_t * const key,
fp_to_unsigned_bin(unconst_fp_int(key->Q->y), d + q_len - Qy_len);
d += q_len;
- assert(d < der + der_max);
+ hal_assert(d < der + der_max);
}
return hal_asn1_encode_spki(hal_asn1_oid_ecPublicKey, hal_asn1_oid_ecPublicKey_len,
@@ -1554,7 +1561,7 @@ static hal_error_t encode_signature_pkcs11(const ecdsa_curve_t * const curve,
const fp_int * const r, const fp_int * const s,
uint8_t *signature, size_t *signature_len, const size_t signature_max)
{
- assert(curve != NULL && r != NULL && s != NULL);
+ hal_assert(curve != NULL && r != NULL && s != NULL);
const size_t n_len = fp_unsigned_bin_size(unconst_fp_int(curve->n));
const size_t r_len = fp_unsigned_bin_size(unconst_fp_int(r));
@@ -1589,7 +1596,7 @@ static hal_error_t decode_signature_pkcs11(const ecdsa_curve_t * const curve,
fp_int *r, fp_int *s,
const uint8_t * const signature, const size_t signature_len)
{
- assert(curve != NULL && r != NULL && s != NULL);
+ hal_assert(curve != NULL && r != NULL && s != NULL);
if (signature == NULL || (signature_len & 1) != 0)
return HAL_ERROR_BAD_ARGUMENTS;
@@ -1695,7 +1702,7 @@ hal_error_t hal_ecdsa_verify(hal_core_t *core,
const uint8_t * const hash, const size_t hash_len,
const uint8_t * const signature, const size_t signature_len)
{
- assert(key != NULL && hash != NULL && signature != NULL);
+ hal_assert(key != NULL && hash != NULL && signature != NULL);
const ecdsa_curve_t * const curve = get_curve(key->curve);
diff --git a/hal.h b/hal.h
index a01b9bd..b544900 100644
--- a/hal.h
+++ b/hal.h
@@ -161,6 +161,8 @@
DEFINE_HAL_ERROR(HAL_ERROR_KEYSTORE_WRONG_BLOCK_TYPE, "Wrong block type in keystore") \
DEFINE_HAL_ERROR(HAL_ERROR_RPC_PROTOCOL_ERROR, "RPC protocol error") \
DEFINE_HAL_ERROR(HAL_ERROR_NOT_IMPLEMENTED, "Not implemented") \
+ DEFINE_HAL_ERROR(HAL_ERROR_CORE_REASSIGNED, "Core has been reassigned since last use") \
+ DEFINE_HAL_ERROR(HAL_ERROR_ASSERTION_FAILED, "Assertion failed") \
DEFINE_HAL_ERROR(HAL_ERROR_HASHSIG_KEY_EXHAUSTED, "Key exhausted") \
DEFINE_HAL_ERROR(HAL_ERROR_NOT_READY, "Not ready for this operation") \
END_OF_HAL_ERROR_LIST
@@ -214,6 +216,12 @@ extern hal_error_t hal_io_wait2(const hal_core_t *core1, const hal_core_t *core2
* insistence on discarding array bounds information makes
* non-delimited character arrays problematic unless we wrap them in a
* structure.
+ *
+ * For performance reasons, we promise that the hal_core_info_t will
+ * be the first element of hal_core_t, so that we can convert between
+ * them using inline functions without completely exposing hal_core_t.
+ * This is icky, but hal_core_base() gets called a lot during I/O, so
+ * it's worth a bit of ick to eliminate some function call overhead.
*/
typedef struct {
@@ -222,16 +230,25 @@ typedef struct {
hal_addr_t base;
} hal_core_info_t;
+typedef uint32_t hal_core_lru_t;
+
+static inline const hal_core_info_t *hal_core_info(const hal_core_t *core)
+{
+ return (const hal_core_info_t *) core;
+}
+
+static inline hal_addr_t hal_core_base(const hal_core_t *core)
+{
+ return core == NULL ? 0 : hal_core_info(core)->base;
+}
+
extern hal_core_t *hal_core_find(const char *name, hal_core_t *core);
-extern const hal_core_info_t *hal_core_info(const hal_core_t *core);
-extern hal_addr_t hal_core_base(const hal_core_t *core);
-extern hal_core_t * hal_core_iterate(hal_core_t *core);
+extern hal_core_t *hal_core_iterate(hal_core_t *core);
extern void hal_core_reset_table(void);
-extern hal_error_t hal_core_alloc(const char *name, hal_core_t **core);
+extern hal_error_t hal_core_alloc(const char *name, hal_core_t **core, hal_core_lru_t *pomace);
+extern hal_error_t hal_core_alloc2(const char *name1, hal_core_t **core1, hal_core_lru_t *pomace1,
+ const char *name2, hal_core_t **core2, hal_core_lru_t *pomace2);
extern void hal_core_free(hal_core_t *core);
-extern void hal_critical_section_start(void);
-extern void hal_critical_section_end(void);
-extern int hal_core_busy(const hal_core_t *core);
/*
* Slightly higher level public API, still working directly with cores.
diff --git a/hal_internal.h b/hal_internal.h
index b698611..94546c3 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -48,6 +48,19 @@
*/
/*
+ * Assertions, using our logger rather than printf() and assuming a
+ * hal_error_t return value.
+ */
+
+#define hal_assert(_whatever_) \
+ do { \
+ if (!(_whatever_)) { \
+ hal_log(HAL_LOG_ERROR, "Assertion failed: %s", #_whatever_); \
+ return HAL_ERROR_ASSERTION_FAILED; \
+ } \
+ } while (0)
+
+/*
* htonl and htons are not available in arm-none-eabi headers or libc.
*/
#ifndef STM32F4XX
@@ -152,6 +165,8 @@ extern void hal_critical_section_start(void);
extern void hal_critical_section_end(void);
extern void hal_ks_lock(void);
extern void hal_ks_unlock(void);
+extern void hal_rsa_bf_lock(void);
+extern void hal_rsa_bf_unlock(void);
extern void hal_task_yield(void);
extern void hal_task_yield_maybe(void);
@@ -529,15 +544,8 @@ typedef struct {
int hint;
/*
- * This might be where we'd stash a (hal_core_t *) pointing to a
- * core which has already been loaded with the key, if we were
- * trying to be clever about using multiple signing cores. Moot
- * point (ie, no way we could possibly test such a thing) as long as
- * the FPGA is too small to hold more than one modexp core and ECDSA
- * is entirely software, so skip it for now, but the implied
- * semantics are interesting: a pkey handle starts to resemble an
- * initialized signing core, and once all the cores are in use, one
- * can't load another key without closing an existing pkey handle.
+ * This might be where we'd stash one or more (hal_core_t *)
+ * pointing to cores which have already been loaded with the key.
*/
} hal_pkey_slot_t;
diff --git a/hal_io_fmc.c b/hal_io_fmc.c
index 0d49f1e..8a32921 100644
--- a/hal_io_fmc.c
+++ b/hal_io_fmc.c
@@ -44,6 +44,15 @@
#include "hal.h"
#include "hal_internal.h"
+/*
+ * Even no-op debugging code shows up in profiling if it's in an inner
+ * loop which runs often enough, so we leave now this off by default
+ * at compile time.
+ */
+#ifndef HAL_IO_FMC_DEBUG
+#define HAL_IO_FMC_DEBUG 0
+#endif
+
static int debug = 0;
static int inited = 0;
@@ -68,17 +77,24 @@ void hal_io_set_debug(int onoff)
debug = onoff;
}
-static void dump(char *label, hal_addr_t offset, const uint8_t *buf, size_t len)
+#if HAL_IO_FMC_DEBUG
+
+static inline void dump(const char *label, const hal_addr_t offset, const uint8_t * const buf, const size_t len)
{
if (debug) {
- size_t i;
- printf("%s %04x [", label, (unsigned int)offset);
- for (i = 0; i < len; ++i)
- printf(" %02x", buf[i]);
- printf(" ]\n");
+ char hex[len * 3 + 1];
+ for (size_t i = 0; i < len; ++i)
+ sprintf(hex + 3 * i, " %02x", buf[i]);
+ hal_log(HAL_LOG_DEBUG, "%s %04x [%s ]", label, (unsigned int) offset, hex);
}
}
+#else
+
+#define dump(...)
+
+#endif
+
hal_error_t hal_io_write(const hal_core_t *core, hal_addr_t offset, const uint8_t *buf, size_t len)
{
hal_error_t err;
@@ -98,7 +114,7 @@ hal_error_t hal_io_write(const hal_core_t *core, hal_addr_t offset, const uint8_
for (; len > 0; offset += 4, buf += 4, len -= 4) {
uint32_t val;
val = htonl(*(uint32_t *)buf);
- fmc_write_32(offset, &val);
+ fmc_write_32(offset, val);
}
return HAL_OK;
@@ -108,7 +124,6 @@ hal_error_t hal_io_read(const hal_core_t *core, hal_addr_t offset, uint8_t *buf,
{
uint8_t *rbuf = buf;
int rlen = len;
- hal_addr_t orig_offset = offset;
hal_error_t err;
if (core == NULL)
@@ -120,6 +135,8 @@ hal_error_t hal_io_read(const hal_core_t *core, hal_addr_t offset, uint8_t *buf,
if ((err = init()) != HAL_OK)
return err;
+ dump("read ", offset + hal_core_base(core), buf, len);
+
offset = fmc_offset(offset + hal_core_base(core));
for (; rlen > 0; offset += 4, rbuf += 4, rlen -= 4) {
uint32_t val;
@@ -127,8 +144,6 @@ hal_error_t hal_io_read(const hal_core_t *core, hal_addr_t offset, uint8_t *buf,
*(uint32_t *)rbuf = ntohl(val);
}
- dump("read ", orig_offset + hal_core_base(core), buf, len);
-
return HAL_OK;
}
diff --git a/hash.c b/hash.c
index d1e55ff..2a63900 100644
--- a/hash.c
+++ b/hash.c
@@ -4,7 +4,7 @@
* HAL interface to Cryptech hash cores.
*
* Authors: Joachim Strömbergson, Paul Selkirk, Rob Austein
- * Copyright (c) 2014-2016, NORDUnet A/S
+ * Copyright (c) 2014-2018, NORDUnet A/S
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@@ -81,6 +80,11 @@ static hal_error_t sw_hash_core_sha512(hal_hash_state_t *);
#endif /* HAL_ENABLE_SOFTWARE_HASH_CORES */
+#if HAL_ONLY_USE_SOFTWARE_HASH_CORES
+#define hal_core_alloc(x, y, z) HAL_ERROR_CORE_NOT_FOUND
+#define hal_core_free(x)
+#endif
+
/*
* HMAC magic numbers.
*/
@@ -119,10 +123,12 @@ struct hal_hash_state {
size_t block_used; /* How much of the block we've used */
unsigned block_count; /* Blocks sent */
unsigned flags;
+ hal_core_lru_t pomace; /* Private data for hal_core_alloc() */
};
-#define STATE_FLAG_STATE_ALLOCATED 0x1 /* State buffer dynamically allocated */
+#define STATE_FLAG_STATE_ALLOCATED 0x1 /* State buffer in use */
#define STATE_FLAG_SOFTWARE_CORE 0x2 /* Use software rather than hardware core */
+#define STATE_FLAG_FREE_CORE 0x4 /* Free core after use */
/*
* HMAC state. Right now this just holds the key block and a hash
@@ -330,7 +336,7 @@ static inline hal_hmac_state_t *alloc_static_hmac_state(void)
* This is only used by the software hash cores, but it's simpler to define it unconditionally.
*/
-static inline void swytebop(void *out_, const void * const in_, const size_t n, const size_t w)
+static inline hal_error_t swytebop(void *out_, const void * const in_, const size_t n, const size_t w)
{
const uint8_t order[] = { 0x01, 0x02, 0x03, 0x04 };
@@ -338,23 +344,24 @@ static inline void swytebop(void *out_, const void * const in_, const size_t n,
uint8_t *out = out_;
/* w must be a power of two */
- assert(in != out && in != NULL && out != NULL && w && !(w & (w - 1)));
+ hal_assert(in != out && in != NULL && out != NULL && w && !(w & (w - 1)));
switch (* (uint32_t *) order) {
case 0x01020304:
memcpy(out, in, n);
- return;
+ break;
case 0x04030201:
for (size_t i = 0; i < n; i += w)
for (size_t j = 0; j < w && i + j < n; j++)
out[i + j] = in[i + w - j - 1];
- return;
+ break;
default:
- assert((* (uint32_t *) order) == 0x01020304 || (* (uint32_t *) order) == 0x04030201);
+ hal_assert((* (uint32_t *) order) == 0x01020304 || (* (uint32_t *) order) == 0x04030201);
}
+ return HAL_OK;
}
/*
@@ -364,28 +371,37 @@ static inline void swytebop(void *out_, const void * const in_, const size_t n,
static inline hal_error_t check_core(hal_core_t **core,
const hal_hash_descriptor_t * const descriptor,
- unsigned *flags)
+ unsigned *flags,
+ hal_core_lru_t *pomace)
{
- assert(descriptor != NULL && descriptor->driver != NULL);
+ if (core == NULL || descriptor == NULL || descriptor->driver == NULL || flags == NULL)
+ return HAL_ERROR_IMPOSSIBLE;
-#if HAL_ONLY_USE_SOFTWARE_HASH_CORES
hal_error_t err = HAL_ERROR_CORE_NOT_FOUND;
-#else
- hal_error_t err = hal_core_alloc(descriptor->core_name, core);
-#endif
-#if HAL_ENABLE_SOFTWARE_HASH_CORES
- if ((err == HAL_ERROR_CORE_NOT_FOUND || err == HAL_ERROR_CORE_BUSY) &&
- descriptor->driver->sw_core) {
+#if !HAL_ONLY_USE_SOFTWARE_HASH_CORES
+
+ if (*core != NULL)
+ return HAL_OK;
+
+ if ((err = hal_core_alloc(descriptor->core_name, core, pomace)) == HAL_OK) {
+ *flags |= STATE_FLAG_FREE_CORE;
+ return HAL_OK;
+ }
+
+#endif
- *core = NULL;
+ if (*core != NULL)
+ return HAL_ERROR_IMPOSSIBLE;
- if (flags != NULL)
- *flags |= STATE_FLAG_SOFTWARE_CORE;
+#if HAL_ENABLE_SOFTWARE_HASH_CORES
- err = HAL_OK;
+ if (descriptor->driver->sw_core && err == HAL_ERROR_CORE_NOT_FOUND) {
+ *flags |= STATE_FLAG_SOFTWARE_CORE;
+ return HAL_OK;
}
-#endif /* HAL_ENABLE_SOFTWARE_HASH_CORES */
+
+#endif
return err;
}
@@ -414,6 +430,7 @@ hal_error_t hal_hash_initialize(hal_core_t *core,
{
const hal_hash_driver_t * const driver = check_driver(descriptor);
hal_hash_state_t *state = state_buffer;
+ hal_core_lru_t pomace = 0;
unsigned flags = 0;
hal_error_t err;
@@ -423,18 +440,15 @@ hal_error_t hal_hash_initialize(hal_core_t *core,
if (state_buffer != NULL && state_length < descriptor->hash_state_length)
return HAL_ERROR_BAD_ARGUMENTS;
- if ((err = check_core(&core, descriptor, &flags)) != HAL_OK)
+ if ((err = check_core(&core, descriptor, &flags, &pomace)) != HAL_OK)
return err;
-#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES
- /*
- * If we're using a Verilog core that can save/restore state, then we
- * free it after every operation, so that it can possibly be used by
- * another client.
- */
- if (descriptor->can_restore_state)
- hal_core_free(core);
-#endif
+ if ((flags & STATE_FLAG_FREE_CORE) != 0)
+ hal_core_free(core);
+
+ /* A dynamically allocated core that can't restore state isn't going to work. */
+ if (!descriptor->can_restore_state && (flags & STATE_FLAG_FREE_CORE) != 0)
+ return HAL_ERROR_BAD_ARGUMENTS;
if (state_buffer == NULL && (state = alloc_static_hash_state()) == NULL)
return HAL_ERROR_ALLOCATION_FAILURE;
@@ -444,6 +458,7 @@ hal_error_t hal_hash_initialize(hal_core_t *core,
state->driver = driver;
state->core = core;
state->flags = flags | STATE_FLAG_STATE_ALLOCATED;
+ state->pomace = pomace;
*state_ = state;
@@ -451,21 +466,17 @@ hal_error_t hal_hash_initialize(hal_core_t *core,
}
/*
- * Clean up hash state. No-op unless memory was dynamically allocated.
+ * Clean up hash state.
*/
-void hal_hash_cleanup(hal_hash_state_t **state_)
+void hal_hash_cleanup(hal_hash_state_t **state)
{
- if (state_ == NULL)
+ if (state == NULL || *state == NULL)
return;
- hal_hash_state_t *state = *state_;
+ memset(*state, 0, (*state)->descriptor->hash_state_length);
- if (state == NULL || (state->flags & STATE_FLAG_STATE_ALLOCATED) == 0)
- return;
-
- memset(state, 0, state->descriptor->hash_state_length);
- *state_ = NULL;
+ *state = NULL;
}
#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES
@@ -482,7 +493,7 @@ static hal_error_t hash_read_digest(const hal_core_t *core,
{
hal_error_t err;
- assert(digest != NULL && digest_length % 4 == 0);
+ hal_assert(digest != NULL && digest_length % 4 == 0);
if ((err = hal_io_wait_valid(core)) != HAL_OK)
return err;
@@ -501,7 +512,7 @@ static hal_error_t hash_write_digest(const hal_core_t *core,
{
hal_error_t err;
- assert(digest != NULL && digest_length % 4 == 0);
+ hal_assert(digest != NULL && digest_length % 4 == 0);
if ((err = hal_io_wait_ready(core)) != HAL_OK)
return err;
@@ -517,14 +528,14 @@ static hal_error_t hash_write_digest(const hal_core_t *core,
static hal_error_t hash_write_block(hal_hash_state_t * const state)
{
- assert(state != NULL && state->descriptor != NULL && state->driver != NULL);
- assert(state->descriptor->block_length % 4 == 0);
+ hal_assert(state != NULL && state->descriptor != NULL && state->driver != NULL);
+ hal_assert(state->descriptor->block_length % 4 == 0);
- assert(state->descriptor->digest_length <= sizeof(state->core_state) ||
- !state->descriptor->can_restore_state);
+ hal_assert(state->descriptor->digest_length <= sizeof(state->core_state) ||
+ !state->descriptor->can_restore_state);
if (debug)
- fprintf(stderr, "[ %s ]\n", state->block_count == 0 ? "init" : "next");
+ hal_log(HAL_LOG_DEBUG, "[ %s ]\n", state->block_count == 0 ? "init" : "next");
#if HAL_ENABLE_SOFTWARE_HASH_CORES
if ((state->flags & STATE_FLAG_SOFTWARE_CORE) != 0)
@@ -585,22 +596,25 @@ hal_error_t hal_hash_update(hal_hash_state_t *state, /* Opaque state
if (data_buffer_length == 0)
return HAL_OK;
- assert(state->descriptor != NULL && state->driver != NULL);
- assert(state->descriptor->block_length <= sizeof(state->block));
+ hal_assert(state->descriptor != NULL && state->driver != NULL);
+ hal_assert(state->descriptor->block_length <= sizeof(state->block));
-#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES
- if (((state->flags & STATE_FLAG_SOFTWARE_CORE) == 0) &&
- state->descriptor->can_restore_state &&
- (err = hal_core_alloc(state->descriptor->core_name, &state->core)) != HAL_OK)
+ if ((state->flags & STATE_FLAG_FREE_CORE) != 0) {
+ err = hal_core_alloc(state->descriptor->core_name, &state->core, &state->pomace);
+ if (err == HAL_ERROR_CORE_REASSIGNED) {
+ state->core = NULL;
+ err = hal_core_alloc(state->descriptor->core_name, &state->core, &state->pomace);
+ }
+ if (err != HAL_OK)
return err;
-#endif
+ }
while ((n = state->descriptor->block_length - state->block_used) <= data_buffer_length) {
/*
* We have enough data for another complete block.
*/
if (debug)
- fprintf(stderr, "[ Full block, data_buffer_length %lu, used %lu, n %lu, msg_length %llu ]\n",
+ hal_log(HAL_LOG_DEBUG, "[ Full block, data_buffer_length %lu, used %lu, n %lu, msg_length %llu ]\n",
(unsigned long) data_buffer_length, (unsigned long) state->block_used, (unsigned long) n, (unsigned long long)state->msg_length_low);
memcpy(state->block + state->block_used, p, n);
if ((state->msg_length_low += n) < n)
@@ -618,9 +632,9 @@ hal_error_t hal_hash_update(hal_hash_state_t *state, /* Opaque state
* Data left over, but not enough for a full block, stash it.
*/
if (debug)
- fprintf(stderr, "[ Partial block, data_buffer_length %lu, used %lu, n %lu, msg_length %llu ]\n",
+ hal_log(HAL_LOG_DEBUG, "[ Partial block, data_buffer_length %lu, used %lu, n %lu, msg_length %llu ]\n",
(unsigned long) data_buffer_length, (unsigned long) state->block_used, (unsigned long) n, (unsigned long long)state->msg_length_low);
- assert(data_buffer_length < n);
+ hal_assert(data_buffer_length < n);
memcpy(state->block + state->block_used, p, data_buffer_length);
if ((state->msg_length_low += data_buffer_length) < data_buffer_length)
state->msg_length_high++;
@@ -628,10 +642,8 @@ hal_error_t hal_hash_update(hal_hash_state_t *state, /* Opaque state
}
out:
-#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES
- if (state->descriptor->can_restore_state)
+ if ((state->flags & STATE_FLAG_FREE_CORE) != 0)
hal_core_free(state->core);
-#endif
return err;
}
@@ -652,19 +664,22 @@ hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaqu
if (state == NULL || digest_buffer == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
- assert(state->descriptor != NULL && state->driver != NULL);
+ hal_assert(state->descriptor != NULL && state->driver != NULL);
if (digest_buffer_length < state->descriptor->digest_length)
return HAL_ERROR_BAD_ARGUMENTS;
- assert(state->descriptor->block_length <= sizeof(state->block));
+ hal_assert(state->descriptor->block_length <= sizeof(state->block));
-#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES
- if (((state->flags & STATE_FLAG_SOFTWARE_CORE) == 0) &&
- state->descriptor->can_restore_state &&
- (err = hal_core_alloc(state->descriptor->core_name, &state->core)) != HAL_OK)
+ if ((state->flags & STATE_FLAG_FREE_CORE) != 0) {
+ err = hal_core_alloc(state->descriptor->core_name, &state->core, &state->pomace);
+ if (err == HAL_ERROR_CORE_REASSIGNED) {
+ state->core = NULL;
+ err = hal_core_alloc(state->descriptor->core_name, &state->core, &state->pomace);
+ }
+ if (err != HAL_OK)
return err;
-#endif
+ }
/*
* Add padding, then pull result from the core
@@ -674,13 +689,13 @@ hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaqu
bit_length_high = (state->msg_length_high << 3) | (state->msg_length_low >> 61);
/* Initial pad byte */
- assert(state->block_used < state->descriptor->block_length);
+ hal_assert(state->block_used < state->descriptor->block_length);
state->block[state->block_used++] = 0x80;
/* If not enough room for bit count, zero and push current block */
if ((n = state->descriptor->block_length - state->block_used) < state->driver->length_length) {
if (debug)
- fprintf(stderr, "[ Overflow block, used %lu, n %lu, msg_length %llu ]\n",
+ hal_log(HAL_LOG_DEBUG, "[ Overflow block, used %lu, n %lu, msg_length %llu ]\n",
(unsigned long) state->block_used, (unsigned long) n, (unsigned long long)state->msg_length_low);
if (n > 0)
memset(state->block + state->block_used, 0, n);
@@ -692,11 +707,11 @@ hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaqu
/* Pad final block */
n = state->descriptor->block_length - state->block_used;
- assert(n >= state->driver->length_length);
+ hal_assert(n >= state->driver->length_length);
if (n > 0)
memset(state->block + state->block_used, 0, n);
if (debug)
- fprintf(stderr, "[ Final block, used %lu, n %lu, msg_length %llu ]\n",
+ hal_log(HAL_LOG_DEBUG, "[ Final block, used %lu, n %lu, msg_length %llu ]\n",
(unsigned long) state->block_used, (unsigned long) n, (unsigned long long)state->msg_length_low);
p = state->block + state->descriptor->block_length;
for (i = 0; (bit_length_low || bit_length_high) && i < state->driver->length_length; i++) {
@@ -715,10 +730,9 @@ hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaqu
/* All data pushed to core, now we just need to read back the result */
#if HAL_ENABLE_SOFTWARE_HASH_CORES
- if ((state->flags & STATE_FLAG_SOFTWARE_CORE) != 0) {
- swytebop(digest_buffer, state->core_state, state->descriptor->digest_length, state->driver->sw_word_size);
- return HAL_OK;
- }
+ if ((state->flags & STATE_FLAG_SOFTWARE_CORE) != 0)
+ return swytebop(digest_buffer, state->core_state, state->descriptor->digest_length,
+ state->driver->sw_word_size);
#endif
#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES
if ((state->flags & STATE_FLAG_SOFTWARE_CORE) == 0)
@@ -726,9 +740,8 @@ hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaqu
#endif
out:
-#if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES
- hal_core_free(state->core);
-#endif
+ if ((state->flags & STATE_FLAG_FREE_CORE) != 0)
+ hal_core_free(state->core);
return err;
}
@@ -758,7 +771,7 @@ hal_error_t hal_hmac_initialize(hal_core_t *core,
hal_hash_state_t *h = &state->hash_state;
- assert(descriptor->block_length <= sizeof(state->keybuf));
+ hal_assert(descriptor->block_length <= sizeof(state->keybuf));
#if 0
/*
@@ -828,26 +841,17 @@ hal_error_t hal_hmac_initialize(hal_core_t *core,
}
/*
- * Clean up HMAC state. No-op unless memory was dynamically allocated.
+ * Clean up HMAC state.
*/
-void hal_hmac_cleanup(hal_hmac_state_t **state_)
+void hal_hmac_cleanup(hal_hmac_state_t **state)
{
- if (state_ == NULL)
+ if (state == NULL || *state == NULL)
return;
- hal_hmac_state_t *state = *state_;
+ memset(*state, 0, (*state)->hash_state.descriptor->hmac_state_length);
- if (state == NULL)
- return;
-
- hal_hash_state_t *h = &state->hash_state;
-
- if ((h->flags & STATE_FLAG_STATE_ALLOCATED) == 0)
- return;
-
- memset(state, 0, h->descriptor->hmac_state_length);
- *state_ = NULL;
+ *state = NULL;
}
/*
@@ -878,15 +882,19 @@ hal_error_t hal_hmac_finalize(hal_hmac_state_t *state,
uint8_t d[HAL_MAX_HASH_DIGEST_LENGTH];
hal_error_t err;
- assert(descriptor != NULL && descriptor->digest_length <= sizeof(d));
+ hal_assert(descriptor != NULL && descriptor->digest_length <= sizeof(d));
/*
* Finish up inner hash and extract digest, then perform outer hash
* to get HMAC. Key was prepared for this in hal_hmac_initialize().
+ *
+ * For silly reasons, reusing the core value from the hash state
+ * block here would require nontrivial refactoring, so for the
+ * moment pass NULL and let the core allocator deal. Fix someday.
*/
if ((err = hal_hash_finalize(h, d, sizeof(d))) != HAL_OK ||
- (err = hal_hash_initialize(h->core, descriptor, &h, &state->hash_state,
+ (err = hal_hash_initialize(NULL, descriptor, &h, &state->hash_state,
sizeof(state->hash_state))) != HAL_OK ||
(err = hal_hash_update(h, state->keybuf, descriptor->block_length)) != HAL_OK ||
(err = hal_hash_update(h, d, descriptor->digest_length)) != HAL_OK ||
@@ -971,12 +979,12 @@ static const uint64_t sha512_K[80] = {
* confusing enough without adding a lot of unnecessary C macro baggage).
*/
-static inline uint32_t rot_l_32(uint32_t x, unsigned n) { assert(n < 32); return ((x << n) | (x >> (32 - n))); }
-static inline uint32_t rot_r_32(uint32_t x, unsigned n) { assert(n < 32); return ((x >> n) | (x << (32 - n))); }
-static inline uint32_t lsh_r_32(uint32_t x, unsigned n) { assert(n < 32); return (x >> n); }
+static inline uint32_t rot_l_32(uint32_t x, unsigned n) { return ((x << n) | (x >> (32 - n))); }
+static inline uint32_t rot_r_32(uint32_t x, unsigned n) { return ((x >> n) | (x << (32 - n))); }
+static inline uint32_t lsh_r_32(uint32_t x, unsigned n) { return (x >> n); }
-static inline uint64_t rot_r_64(uint64_t x, unsigned n) { assert(n < 64); return ((x >> n) | (x << (64 - n))); }
-static inline uint64_t lsh_r_64(uint64_t x, unsigned n) { assert(n < 64); return (x >> n); }
+static inline uint64_t rot_r_64(uint64_t x, unsigned n) { return ((x >> n) | (x << (64 - n))); }
+static inline uint64_t lsh_r_64(uint64_t x, unsigned n) { return (x >> n); }
static inline uint32_t Choose_32( uint32_t x, uint32_t y, uint32_t z) { return (z ^ (x & (y ^ z))); }
static inline uint32_t Majority_32(uint32_t x, uint32_t y, uint32_t z) { return ((x & y) | (z & (x | y))); }
@@ -999,8 +1007,8 @@ static inline uint64_t Gamma1_64(uint64_t x) { return rot_r_64(x, 19) ^ rot_r_64
* Offset into hash state. In theory, this should works out to compile-time constants after optimization.
*/
-static inline int sha1_pos(int i, int j) { assert(i >= 0 && j >= 0 && j < 5); return (5 + j - (i % 5)) % 5; }
-static inline int sha2_pos(int i, int j) { assert(i >= 0 && j >= 0 && j < 8); return (8 + j - (i % 8)) % 8; }
+static inline int sha1_pos(int i, int j) { return (5 + j - (i % 5)) % 5; }
+static inline int sha2_pos(int i, int j) { return (8 + j - (i % 8)) % 8; }
/*
* Software implementation of SHA-1 block algorithm.
@@ -1009,6 +1017,7 @@ static inline int sha2_pos(int i, int j) { assert(i >= 0 && j >= 0 && j < 8); re
static hal_error_t sw_hash_core_sha1(hal_hash_state_t *state)
{
static const uint32_t iv[5] = {0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL};
+ hal_error_t err;
if (state == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
@@ -1020,7 +1029,8 @@ static hal_error_t sw_hash_core_sha1(hal_hash_state_t *state)
memcpy(S, H, sizeof(S));
- swytebop(W, state->block, 16 * sizeof(*W), sizeof(*W));
+ if ((err = swytebop(W, state->block, 16 * sizeof(*W), sizeof(*W))) != HAL_OK)
+ return err;
for (int i = 16; i < 80; i++)
W[i] = rot_l_32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
@@ -1035,7 +1045,7 @@ static hal_error_t sw_hash_core_sha1(hal_hash_state_t *state)
else f = Parity_32( S[b], S[c], S[d]), k = 0xCA62C1D6UL;
if (debug)
- fprintf(stderr,
+ hal_log(HAL_LOG_DEBUG,
"[Round %02d < a = 0x%08x, b = 0x%08x, c = 0x%08x, d = 0x%08x, e = 0x%08x, f = 0x%08x, k = 0x%08x, w = 0x%08x]\n",
i, (unsigned)S[a], (unsigned)S[b], (unsigned)S[c], (unsigned)S[d], (unsigned)S[e], (unsigned)f, (unsigned)k, (unsigned)W[i]);
@@ -1043,7 +1053,7 @@ static hal_error_t sw_hash_core_sha1(hal_hash_state_t *state)
S[b] = rot_l_32(S[b], 30);
if (debug)
- fprintf(stderr, "[Round %02d > a = 0x%08x, b = 0x%08x, c = 0x%08x, d = 0x%08x, e = 0x%08x]\n",
+ hal_log(HAL_LOG_DEBUG, "[Round %02d > a = 0x%08x, b = 0x%08x, c = 0x%08x, d = 0x%08x, e = 0x%08x]\n",
i, (unsigned)S[a], (unsigned)S[b], (unsigned)S[c], (unsigned)S[d], (unsigned)S[e]);
}
@@ -1066,6 +1076,8 @@ static hal_error_t sw_hash_core_sha256(hal_hash_state_t *state)
static const uint32_t sha256_iv[8] = {0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL};
+ hal_error_t err;
+
if (state == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
@@ -1081,7 +1093,8 @@ static hal_error_t sw_hash_core_sha256(hal_hash_state_t *state)
memcpy(S, H, sizeof(S));
- swytebop(W, state->block, 16 * sizeof(*W), sizeof(*W));
+ if ((err = swytebop(W, state->block, 16 * sizeof(*W), sizeof(*W))) != HAL_OK)
+ return err;
for (int i = 16; i < 64; i++)
W[i] = Gamma1_32(W[i - 2]) + W[i - 7] + Gamma0_32(W[i - 15]) + W[i - 16];
@@ -1123,6 +1136,8 @@ static hal_error_t sw_hash_core_sha512(hal_hash_state_t *state)
sha512_256_iv[8] = {0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL, 0x2393B86B6F53B151ULL, 0x963877195940EABDULL,
0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL, 0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL};
+ hal_error_t err;
+
if (state == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
@@ -1140,7 +1155,8 @@ static hal_error_t sw_hash_core_sha512(hal_hash_state_t *state)
memcpy(S, H, sizeof(S));
- swytebop(W, state->block, 16 * sizeof(*W), sizeof(*W));
+ if ((err = swytebop(W, state->block, 16 * sizeof(*W), sizeof(*W))) != HAL_OK)
+ return err;
for (int i = 16; i < 80; i++)
W[i] = Gamma1_64(W[i - 2]) + W[i - 7] + Gamma0_64(W[i - 15]) + W[i - 16];
diff --git a/ks.c b/ks.c
index c848056..a682cd2 100644
--- a/ks.c
+++ b/ks.c
@@ -620,6 +620,7 @@ hal_error_t hal_ks_fetch(hal_ks_t *ks,
hal_error_t err = HAL_OK;
hal_ks_block_t *block;
+ size_t k_der_len = 0;
unsigned b;
hal_ks_lock();
@@ -627,17 +628,18 @@ hal_error_t hal_ks_fetch(hal_ks_t *ks,
if ((err = hal_ks_index_find(ks, &slot->name, &b, &slot->hint)) != HAL_OK ||
(err = hal_ks_block_test_owner(ks, b, slot->client, slot->session)) != HAL_OK ||
(err = hal_ks_block_read_cached(ks, b, &block)) != HAL_OK)
- goto done;
+ goto unlock;
if (hal_ks_block_get_type(block) != HAL_KS_BLOCK_TYPE_KEY) {
err = HAL_ERROR_KEYSTORE_WRONG_BLOCK_TYPE; /* HAL_ERROR_KEY_NOT_FOUND */
- goto done;
+ goto unlock;
}
hal_ks_cache_mark_used(ks, block, b);
hal_ks_key_block_t *k = &block->key;
+ k_der_len = k->der_len;
slot->type = k->type;
slot->curve = k->curve;
slot->flags = k->flags;
@@ -645,6 +647,15 @@ hal_error_t hal_ks_fetch(hal_ks_t *ks,
if (der == NULL && der_len != NULL)
*der_len = k->der_len;
+ if (der != NULL && k_der_len <= der_max)
+ memcpy(der, k->der, k_der_len);
+
+ unlock:
+ hal_ks_unlock();
+
+ if (err != HAL_OK)
+ return err;
+
if (der != NULL) {
uint8_t kek[KEK_LENGTH];
@@ -657,13 +668,11 @@ 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)
- err = hal_aes_keyunwrap(NULL, kek, kek_len, k->der, k->der_len, der, der_len);
+ err = hal_aes_keyunwrap(NULL, kek, kek_len, der, k_der_len, der, der_len);
memset(kek, 0, sizeof(kek));
}
- done:
- hal_ks_unlock();
return err;
}
diff --git a/ks_attribute.c b/ks_attribute.c
index 1eefefb..9e66994 100644
--- a/ks_attribute.c
+++ b/ks_attribute.c
@@ -33,7 +33,6 @@
*/
#include <string.h>
-#include <assert.h>
#include "hal.h"
#include "hal_internal.h"
diff --git a/ks_token.c b/ks_token.c
index 1676bc0..e68056d 100644
--- a/ks_token.c
+++ b/ks_token.c
@@ -44,7 +44,6 @@
#include <stddef.h>
#include <string.h>
-#include <assert.h>
#include "hal.h"
#include "hal_internal.h"
diff --git a/ks_volatile.c b/ks_volatile.c
index 75d7fcb..10fff9a 100644
--- a/ks_volatile.c
+++ b/ks_volatile.c
@@ -37,7 +37,6 @@
*/
#include <string.h>
-#include <assert.h>
#include "hal.h"
#include "hal_internal.h"
diff --git a/locks.c b/locks.c
index 72af43b..7411143 100644
--- a/locks.c
+++ b/locks.c
@@ -77,29 +77,26 @@
* Critical sections -- disable preemption BRIEFLY.
*/
-WEAK_FUNCTION void hal_critical_section_start(void)
-{
- return;
-}
-
-WEAK_FUNCTION void hal_critical_section_end(void)
-{
- return;
-}
+WEAK_FUNCTION void hal_critical_section_start(void) { return; }
+WEAK_FUNCTION void hal_critical_section_end(void) { return; }
/*
* Keystore lock -- lock call blocks indefinitely.
*/
-WEAK_FUNCTION void hal_ks_lock(void)
-{
- return;
-}
+WEAK_FUNCTION void hal_ks_lock(void) { return; }
+WEAK_FUNCTION void hal_ks_unlock(void) { return; }
-WEAK_FUNCTION void hal_ks_unlock(void)
-{
- return;
-}
+/*
+ * RSA blinding cache lock -- lock call blocks indefinitely.
+ */
+
+WEAK_FUNCTION void hal_rsa_bf_lock(void) { return; }
+WEAK_FUNCTION void hal_rsa_bf_unlock(void) { return; }
+
+/*
+ * Non-preemptive task yield.
+ */
WEAK_FUNCTION void hal_task_yield(void)
{
diff --git a/mkmif.c b/mkmif.c
index bc852ef..fb1e7ed 100644
--- a/mkmif.c
+++ b/mkmif.c
@@ -45,63 +45,72 @@ typedef union {
hal_error_t hal_mkmif_init(hal_core_t *core)
{
+ const int free_core = core == NULL;
byteword_t cmd;
hal_error_t err;
cmd.word = htonl(MKMIF_CTRL_CMD_INIT);
- if ((err = hal_core_alloc(MKMIF_NAME, &core)) != HAL_OK)
+ if (free_core && (err = hal_core_alloc(MKMIF_NAME, &core, NULL)) != HAL_OK)
return err;
if ((err = hal_io_write(core, MKMIF_ADDR_CTRL, cmd.byte, 4)) == HAL_OK)
err = hal_io_wait_ready(core);
- hal_core_free(core);
+ if (free_core)
+ hal_core_free(core);
return err;
}
hal_error_t hal_mkmif_set_clockspeed(hal_core_t *core, const uint32_t divisor)
{
+ const int free_core = core == NULL;
byteword_t data;
hal_error_t err;
data.word = htonl(divisor);
- if ((err = hal_core_alloc(MKMIF_NAME, &core)) != HAL_OK)
+ if (free_core && (err = hal_core_alloc(MKMIF_NAME, &core, NULL)) != HAL_OK)
return err;
err = hal_io_write(core, MKMIF_ADDR_SCLK_DIV, data.byte, 4);
- hal_core_free(core);
+ if (free_core)
+ hal_core_free(core);
+
return err;
}
hal_error_t hal_mkmif_get_clockspeed(hal_core_t *core, uint32_t *divisor)
{
+ const int free_core = core == NULL;
byteword_t data;
hal_error_t err;
- if ((err = hal_core_alloc(MKMIF_NAME, &core)) != HAL_OK)
+ if (free_core && (err = hal_core_alloc(MKMIF_NAME, &core, NULL)) != HAL_OK)
return err;
if ((err = hal_io_read(core, MKMIF_ADDR_SCLK_DIV, data.byte, 4)) == HAL_OK)
*divisor = htonl(data.word);
- hal_core_free(core);
+ if (free_core)
+ hal_core_free(core);
+
return err;
}
hal_error_t hal_mkmif_write(hal_core_t *core, uint32_t addr, const uint8_t *buf, size_t len)
{
+ const int free_core = core == NULL;
+ hal_error_t err = HAL_OK;
byteword_t cmd;
- hal_error_t err;
if (len % 4 != 0)
return HAL_ERROR_IO_BAD_COUNT;
cmd.word = htonl(MKMIF_CTRL_CMD_WRITE);
- if ((err = hal_core_alloc(MKMIF_NAME, &core)) == HAL_OK) {
+ if (!free_core || (err = hal_core_alloc(MKMIF_NAME, &core, NULL)) == HAL_OK) {
for (; len > 0; addr += 4, buf += 4, len -= 4) {
byteword_t write_addr;
write_addr.word = htonl((uint32_t)addr);
@@ -113,7 +122,9 @@ hal_error_t hal_mkmif_write(hal_core_t *core, uint32_t addr, const uint8_t *buf,
}
}
- hal_core_free(core);
+ if (free_core)
+ hal_core_free(core);
+
return err;
}
@@ -128,15 +139,16 @@ hal_error_t hal_mkmif_write_word(hal_core_t *core, uint32_t addr, const uint32_t
hal_error_t hal_mkmif_read(hal_core_t *core, uint32_t addr, uint8_t *buf, size_t len)
{
+ const int free_core = core == NULL;
+ hal_error_t err = HAL_OK;
byteword_t cmd;
- hal_error_t err;
if (len % 4 != 0)
return HAL_ERROR_IO_BAD_COUNT;
cmd.word = htonl(MKMIF_CTRL_CMD_READ);
- if ((err = hal_core_alloc(MKMIF_NAME, &core)) != HAL_OK)
+ if (free_core && (err = hal_core_alloc(MKMIF_NAME, &core, NULL)) != HAL_OK)
return err;
for (; len > 0; addr += 4, buf += 4, len -= 4) {
@@ -149,7 +161,9 @@ hal_error_t hal_mkmif_read(hal_core_t *core, uint32_t addr, uint8_t *buf, size_t
break;
}
- hal_core_free(core);
+ if (free_core)
+ hal_core_free(core);
+
return err;
}
diff --git a/modexp.c b/modexp.c
index 37f5e0e..a5172ee 100644
--- a/modexp.c
+++ b/modexp.c
@@ -265,7 +265,6 @@ static inline hal_error_t extract_result(hal_modexp_arg_t *a)
{
/*
* Extract results from the main calculation and we're done.
- * Hardly seems worth making this a separate function.
*/
return get_buffer(a->core, MODEXPA7_ADDR_RESULT, a->result, a->mod_len);
@@ -282,16 +281,23 @@ hal_error_t hal_modexp(const int precalc, hal_modexp_arg_t *a)
if ((err = check_args(a)) != HAL_OK)
return err;
- if ((err = hal_core_alloc(MODEXPA7_NAME, &a->core)) == HAL_OK &&
- (err = setup_precalc(precalc, a)) == HAL_OK &&
+ const int free_core = a->core == NULL;
+
+ if ((!free_core ||
+ (err = hal_core_alloc(MODEXPA7_NAME, &a->core, NULL)) == HAL_OK) &&
+ (err = setup_precalc(precalc, a)) == HAL_OK &&
(!precalc ||
- (err = hal_io_wait_ready(a->core)) == HAL_OK) &&
- (err = setup_calc(precalc, a)) == HAL_OK &&
- (err = hal_io_wait_valid(a->core)) == HAL_OK &&
- (err = extract_result(a)) == HAL_OK)
+ (err = hal_io_wait_ready(a->core)) == HAL_OK) &&
+ (err = setup_calc(precalc, a)) == HAL_OK &&
+ (err = hal_io_wait_valid(a->core)) == HAL_OK &&
+ (err = extract_result(a)) == HAL_OK)
err = HAL_OK;
- hal_core_free(a->core);
+ if (free_core) {
+ hal_core_free(a->core);
+ a->core = NULL;
+ }
+
return err;
}
@@ -301,27 +307,38 @@ hal_error_t hal_modexp(const int precalc, hal_modexp_arg_t *a)
hal_error_t hal_modexp2(const int precalc, hal_modexp_arg_t *a1, hal_modexp_arg_t *a2)
{
+ int free_core = 0;
hal_error_t err;
if ((err = check_args(a1)) != HAL_OK ||
(err = check_args(a2)) != HAL_OK)
return err;
- if ((err = hal_core_alloc2(MODEXPA7_NAME, &a1->core,
- MODEXPA7_NAME, &a2->core)) == HAL_OK &&
- (err = setup_precalc(precalc, a1)) == HAL_OK &&
- (err = setup_precalc(precalc, a2)) == HAL_OK &&
+ if (a1->core == NULL && a2->core == NULL)
+ free_core = 1;
+ else if (a1->core == NULL || a2->core == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if ((!free_core ||
+ (err = hal_core_alloc2(MODEXPA7_NAME, &a1->core, NULL,
+ MODEXPA7_NAME, &a2->core, NULL)) == 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 = setup_calc(precalc, a1)) == HAL_OK &&
- (err = setup_calc(precalc, a2)) == HAL_OK &&
- (err = hal_io_wait_valid2(a1->core, a2->core)) == HAL_OK &&
- (err = extract_result(a1)) == HAL_OK &&
- (err = extract_result(a2)) == HAL_OK)
+ (err = hal_io_wait_ready2(a1->core, a2->core)) == 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 &&
+ (err = extract_result(a1)) == HAL_OK &&
+ (err = extract_result(a2)) == HAL_OK)
err = HAL_OK;
- hal_core_free(a1->core);
- hal_core_free(a2->core);
+ if (free_core) {
+ hal_core_free(a1->core);
+ hal_core_free(a2->core);
+ a1->core = a2->core = NULL;
+ }
+
return err;
}
diff --git a/pbkdf2.c b/pbkdf2.c
index 87ff574..be9e672 100644
--- a/pbkdf2.c
+++ b/pbkdf2.c
@@ -34,7 +34,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <assert.h>
#include <string.h>
#include <stdint.h>
@@ -53,7 +52,7 @@ static hal_error_t do_hmac(hal_core_t *core,
const uint32_t block,
uint8_t * mac, const size_t mac_len)
{
- assert(d != NULL && pw != NULL && data != NULL && mac != NULL);
+ hal_assert(d != NULL && pw != NULL && data != NULL && mac != NULL);
uint8_t sb[d->hmac_state_length];
hal_hmac_state_t *s;
@@ -96,9 +95,9 @@ hal_error_t hal_pbkdf2(hal_core_t *core,
iterations_desired == 0)
return HAL_ERROR_BAD_ARGUMENTS;
- assert(sizeof(statebuf) >= descriptor->hmac_state_length);
- assert(sizeof(result) >= descriptor->digest_length);
- assert(sizeof(mac) >= descriptor->digest_length);
+ hal_assert(sizeof(statebuf) >= descriptor->hmac_state_length);
+ hal_assert(sizeof(result) >= descriptor->digest_length);
+ hal_assert(sizeof(mac) >= descriptor->digest_length);
/* Output length check per RFC 2989 5.2. */
if ((uint64_t) derived_key_length > ((uint64_t) 0xFFFFFFFF) * descriptor->block_length)
diff --git a/rpc_client.c b/rpc_client.c
index 2fb8ae6..e97289e 100644
--- a/rpc_client.c
+++ b/rpc_client.c
@@ -33,8 +33,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <assert.h>
-
#include "hal.h"
#include "hal_internal.h"
#include "xdr_internal.h"
@@ -46,7 +44,7 @@
#if HAL_RPC_CLIENT_DEBUG
#include <stdio.h>
-#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { printf("%s returned %d (%s)\n", #op, _err_, hal_error_string(_err_)); return _err_; } } while (0)
+#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { hal_log(HAL_LOG_DEBUG, "%s returned %d (%s)", #op, _err_, hal_error_string(_err_)); return _err_; } } while (0)
#else
#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { return _err_; } } while (0)
#endif
@@ -74,14 +72,14 @@ static hal_error_t read_matching_packet(const rpc_func_num_t expected_func,
size_t ilen = inbuf_max;
hal_error_t err;
- assert(inbuf != NULL && iptr != NULL && ilimit != NULL);
+ hal_assert(inbuf != NULL && iptr != NULL && ilimit != NULL);
do {
if ((err = hal_rpc_recv(inbuf, &ilen)) != HAL_OK)
return err;
- assert(ilen <= inbuf_max);
+ hal_assert(ilen <= inbuf_max);
*iptr = inbuf;
*ilimit = inbuf + ilen;
diff --git a/rpc_pkcs1.c b/rpc_pkcs1.c
index 2dcf9dd..1cf5cfd 100644
--- a/rpc_pkcs1.c
+++ b/rpc_pkcs1.c
@@ -32,8 +32,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <assert.h>
-
#include "hal.h"
#include "hal_internal.h"
@@ -46,7 +44,7 @@ hal_error_t hal_rpc_pkcs1_construct_digestinfo(const hal_hash_handle_t handle,
uint8_t *digest_info, size_t *digest_info_len,
const size_t digest_info_max)
{
- assert(digest_info != NULL && digest_info_len != NULL);
+ hal_assert(digest_info != NULL && digest_info_len != NULL);
hal_digest_algorithm_t alg;
size_t len, alg_len;
@@ -62,7 +60,7 @@ hal_error_t hal_rpc_pkcs1_construct_digestinfo(const hal_hash_handle_t handle,
if (*digest_info_len >= digest_info_max)
return HAL_ERROR_RESULT_TOO_LONG;
- assert(*digest_info_len < 130);
+ hal_assert(*digest_info_len < 130);
uint8_t *d = digest_info;
@@ -76,7 +74,7 @@ hal_error_t hal_rpc_pkcs1_construct_digestinfo(const hal_hash_handle_t handle,
*d++ = 0x04; /* OCTET STRING */
*d++ = (uint8_t) len;
- assert(digest_info + *digest_info_len == d + len);
+ hal_assert(digest_info + *digest_info_len == d + len);
return hal_rpc_hash_finalize(handle, d, len);
}
diff --git a/rpc_pkey.c b/rpc_pkey.c
index 1aee050..e1521af 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -34,7 +34,6 @@
*/
#include <string.h>
-#include <assert.h>
#include "hal.h"
#include "hal_internal.h"
@@ -74,8 +73,6 @@ static inline hal_pkey_slot_t *alloc_slot(const hal_key_flags_t flags)
uint32_t glop = ++next_glop << 16;
next_glop %= 0x7FFF;
- assert((glop & HAL_PKEY_HANDLE_TOKEN_FLAG) == 0);
-
if ((flags & HAL_KEY_FLAG_TOKEN) != 0)
glop |= HAL_PKEY_HANDLE_TOKEN_FLAG;
@@ -225,7 +222,7 @@ static inline hal_error_t check_writable(const hal_client_handle_t client,
static inline hal_error_t get_nonzero_random(uint8_t *buffer, size_t n)
{
- assert(buffer != NULL);
+ hal_assert(buffer != NULL);
uint32_t word = 0;
hal_error_t err;
@@ -261,7 +258,7 @@ static hal_error_t pkcs1_5_pad(const uint8_t * const data, const size_t data_len
uint8_t *block, const size_t block_len,
const uint8_t type)
{
- assert(data != NULL && block != NULL && (type == 0x01 || type == 0x02));
+ hal_assert(data != NULL && block != NULL && (type == 0x01 || type == 0x02));
hal_error_t err;
@@ -331,7 +328,7 @@ static hal_error_t pkey_local_load(const hal_client_handle_t client,
const uint8_t * const der, const size_t der_len,
const hal_key_flags_t flags)
{
- assert(pkey != NULL && name != NULL && der != NULL);
+ hal_assert(pkey != NULL && name != NULL && der != NULL);
hal_curve_name_t curve;
hal_pkey_slot_t *slot;
@@ -375,7 +372,7 @@ static hal_error_t pkey_local_open(const hal_client_handle_t client,
hal_pkey_handle_t *pkey,
const hal_uuid_t * const name)
{
- assert(pkey != NULL && name != NULL);
+ hal_assert(pkey != NULL && name != NULL);
hal_pkey_slot_t *slot;
hal_error_t err;
@@ -419,7 +416,7 @@ static hal_error_t pkey_local_generate_rsa(const hal_client_handle_t client,
const uint8_t * const public_exponent, const size_t public_exponent_len,
const hal_key_flags_t flags)
{
- assert(pkey != NULL && name != NULL && (key_length & 7) == 0);
+ hal_assert(pkey != NULL && name != NULL && (key_length & 7) == 0);
uint8_t keybuf[hal_rsa_key_t_size];
hal_rsa_key_t *key = NULL;
@@ -478,7 +475,7 @@ static hal_error_t pkey_local_generate_ec(const hal_client_handle_t client,
const hal_curve_name_t curve,
const hal_key_flags_t flags)
{
- assert(pkey != NULL && name != NULL);
+ hal_assert(pkey != NULL && name != NULL);
uint8_t keybuf[hal_ecdsa_key_t_size];
hal_ecdsa_key_t *key = NULL;
@@ -537,7 +534,7 @@ static hal_error_t pkey_local_generate_hashsig(const hal_client_handle_t client,
const lmots_algorithm_t lmots_type,
const hal_key_flags_t flags)
{
- assert(pkey != NULL && name != NULL);
+ hal_assert(pkey != NULL && name != NULL);
hal_hashsig_key_t *key = NULL;
hal_pkey_slot_t *slot;
@@ -837,18 +834,18 @@ static hal_error_t pkey_local_sign_rsa(hal_pkey_slot_t *slot,
uint8_t *keybuf, const size_t keybuf_len,
const uint8_t * const der, const size_t der_len,
const hal_hash_handle_t hash,
- const uint8_t * input, size_t input_len,
- uint8_t * signature, size_t *signature_len, const size_t signature_max)
+ const uint8_t *input, size_t input_len,
+ uint8_t *signature, size_t *signature_len, const size_t signature_max)
{
hal_rsa_key_t *key = NULL;
hal_error_t err;
- assert(signature != NULL && signature_len != NULL);
- assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
+ 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 ||
(err = hal_rsa_key_get_modulus(key, NULL, signature_len, 0)) != HAL_OK)
- return err;
+ return err;
if (*signature_len > signature_max)
return HAL_ERROR_RESULT_TOO_LONG;
@@ -859,7 +856,7 @@ 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 ||
+ 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)
return err;
@@ -886,8 +883,8 @@ static hal_error_t pkey_local_sign_ecdsa(hal_pkey_slot_t *slot,
hal_ecdsa_key_t *key = NULL;
hal_error_t err;
- assert(signature != NULL && signature_len != NULL);
- assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
+ hal_assert(signature != NULL && signature_len != NULL);
+ hal_assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
if ((err = hal_ecdsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len)) != HAL_OK)
return err;
@@ -924,8 +921,8 @@ static hal_error_t pkey_local_sign_hashsig(hal_pkey_slot_t *slot,
hal_hashsig_key_t *key = NULL;
hal_error_t err;
- assert(signature != NULL && signature_len != NULL);
- assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
+ hal_assert(signature != NULL && signature_len != NULL);
+ hal_assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
if ((err = hal_hashsig_private_key_from_der(&key, keybuf, keybuf_len, der, der_len)) != HAL_OK)
return err;
@@ -1022,8 +1019,8 @@ static hal_error_t pkey_local_verify_rsa(uint8_t *keybuf, const size_t keybuf_le
hal_rsa_key_t *key = NULL;
hal_error_t err;
- assert(signature != NULL && signature_len > 0);
- assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
+ hal_assert(signature != NULL && signature_len > 0);
+ hal_assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
switch (type) {
case HAL_KEY_TYPE_RSA_PRIVATE:
@@ -1069,8 +1066,8 @@ static hal_error_t pkey_local_verify_ecdsa(uint8_t *keybuf, const size_t keybuf_
hal_ecdsa_key_t *key = NULL;
hal_error_t err;
- assert(signature != NULL && signature_len > 0);
- assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
+ hal_assert(signature != NULL && signature_len > 0);
+ hal_assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
switch (type) {
case HAL_KEY_TYPE_EC_PRIVATE:
@@ -1113,8 +1110,8 @@ static hal_error_t pkey_local_verify_hashsig(uint8_t *keybuf, const size_t keybu
hal_hashsig_key_t *key = NULL;
hal_error_t err;
- assert(signature != NULL && signature_len > 0);
- assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
+ hal_assert(signature != NULL && signature_len > 0);
+ hal_assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
if ((err = hal_hashsig_public_key_from_der(&key, keybuf, keybuf_len, der, der_len)) != HAL_OK)
return err;
@@ -1240,7 +1237,7 @@ static hal_error_t pkey_local_match(const hal_client_handle_t client,
const unsigned result_max,
const hal_uuid_t * const previous_uuid)
{
- assert(state != NULL && result_len != NULL);
+ hal_assert(state != NULL && result_len != NULL);
static const hal_uuid_t uuid_zero[1] = {{{0}}};
const hal_uuid_t *prev = previous_uuid;
@@ -1325,7 +1322,7 @@ static hal_error_t pkey_local_export(const hal_pkey_handle_t pkey_handle,
uint8_t *pkcs8, size_t *pkcs8_len, const size_t pkcs8_max,
uint8_t *kek, size_t *kek_len, const size_t kek_max)
{
- assert(pkcs8 != NULL && pkcs8_len != NULL && kek != NULL && kek_len != NULL && kek_max > KEK_LENGTH);
+ hal_assert(pkcs8 != NULL && pkcs8_len != NULL && kek != NULL && kek_len != NULL && kek_max > KEK_LENGTH);
uint8_t rsabuf[hal_rsa_key_t_size];
hal_rsa_key_t *rsa = NULL;
@@ -1422,7 +1419,7 @@ static hal_error_t pkey_local_import(const hal_client_handle_t client,
const uint8_t * const kek_, const size_t kek_len,
const hal_key_flags_t flags)
{
- assert(pkey != NULL && name != NULL && pkcs8 != NULL && kek_ != NULL && kek_len > 2);
+ hal_assert(pkey != NULL && name != NULL && pkcs8 != NULL && kek_ != NULL && kek_len > 2);
uint8_t kek[KEK_LENGTH], rsabuf[hal_rsa_key_t_size], der[HAL_KS_WRAPPED_KEYSIZE], *d;
size_t der_len, oid_len, data_len;
diff --git a/rpc_serial.c b/rpc_serial.c
index 0e0e6ff..bae8b83 100644
--- a/rpc_serial.c
+++ b/rpc_serial.c
@@ -92,7 +92,7 @@ hal_error_t hal_serial_init(const char * const device, const uint32_t speed)
termios_speed = B921600;
break;
default:
- fprintf(stderr, "invalid line speed %lu\n", (unsigned long) speed);
+ hal_log(HAL_LOG_ERROR, "invalid line speed %lu\n", (unsigned long) speed);
return HAL_ERROR_RPC_TRANSPORT;
}
diff --git a/rsa.c b/rsa.c
index 01d8290..1b5de7d 100644
--- a/rsa.c
+++ b/rsa.c
@@ -12,7 +12,7 @@
* St Denis's libtomcrypt code.
*
* Authors: Rob Austein
- * Copyright (c) 2015, NORDUnet A/S
+ * Copyright (c) 2015-2018, NORDUnet A/S
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -102,6 +102,15 @@
#endif
/*
+ * How big to make the blinding factors cache.
+ * Zero disables the cache entirely.
+ */
+
+#ifndef HAL_RSA_BLINDING_CACHE_SIZE
+#define HAL_RSA_BLINDING_CACHE_SIZE 2
+#endif
+
+/*
* Whether we want debug output.
*/
@@ -123,6 +132,20 @@ void hal_rsa_set_blinding(const int onoff)
blinding = onoff;
}
+#if HAL_RSA_BLINDING_CACHE_SIZE > 0
+
+typedef struct {
+ unsigned lru;
+ fp_int n[1], bf[1], ubf[1];
+} bfc_slot_t;
+
+static struct {
+ unsigned lru;
+ bfc_slot_t slot[HAL_RSA_BLINDING_CACHE_SIZE];
+} 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
@@ -215,7 +238,7 @@ static hal_error_t modexp(hal_core_t *core,
const fp_int * const msg,
const fp_int * const exp,
const fp_int * const mod,
- fp_int *res,
+ fp_int * res,
uint8_t *coeff, const size_t coeff_len,
uint8_t *mont, const size_t mont_len)
{
@@ -225,29 +248,29 @@ static hal_error_t modexp(hal_core_t *core,
return HAL_ERROR_IMPOSSIBLE;
const size_t msg_len = (fp_unsigned_bin_size(unconst_fp_int(msg)) + 3) & ~3;
- const size_t exp_len = (fp_unsigned_bin_size(unconst_fp_int(exp)) + 3) & ~3;
- const size_t mod_len = (fp_unsigned_bin_size(unconst_fp_int(mod)) + 3) & ~3;
+ const size_t exp_len = (fp_unsigned_bin_size(unconst_fp_int(exp)) + 3) & ~3;
+ const size_t mod_len = (fp_unsigned_bin_size(unconst_fp_int(mod)) + 3) & ~3;
uint8_t msgbuf[msg_len];
uint8_t expbuf[exp_len];
uint8_t modbuf[mod_len];
uint8_t resbuf[mod_len];
- hal_modexp_arg_t args = {
- .core = core,
- .msg = msgbuf, .msg_len = sizeof(msgbuf),
- .exp = expbuf, .exp_len = sizeof(expbuf),
- .mod = modbuf, .mod_len = sizeof(modbuf),
- .result = resbuf, .result_len = sizeof(resbuf),
- .coeff = coeff, .coeff_len = coeff_len,
- .mont = mont, .mont_len = mont_len
- };
+ hal_modexp_arg_t args = {
+ .core = core,
+ .msg = msgbuf, .msg_len = sizeof(msgbuf),
+ .exp = expbuf, .exp_len = sizeof(expbuf),
+ .mod = modbuf, .mod_len = sizeof(modbuf),
+ .result = resbuf, .result_len = sizeof(resbuf),
+ .coeff = coeff, .coeff_len = coeff_len,
+ .mont = mont, .mont_len = mont_len
+ };
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)
- goto fail;
+ goto fail;
fp_read_unsigned_bin(res, resbuf, sizeof(resbuf));
@@ -283,34 +306,34 @@ static hal_error_t modexp2(const int precalc,
return HAL_ERROR_IMPOSSIBLE;
const size_t msg_len = (fp_unsigned_bin_size(unconst_fp_int(msg)) + 3) & ~3;
- const size_t exp1_len = (fp_unsigned_bin_size(unconst_fp_int(exp1)) + 3) & ~3;
- const size_t mod1_len = (fp_unsigned_bin_size(unconst_fp_int(mod1)) + 3) & ~3;
- const size_t exp2_len = (fp_unsigned_bin_size(unconst_fp_int(exp2)) + 3) & ~3;
- const size_t mod2_len = (fp_unsigned_bin_size(unconst_fp_int(mod2)) + 3) & ~3;
+ const size_t exp1_len = (fp_unsigned_bin_size(unconst_fp_int(exp1)) + 3) & ~3;
+ const size_t mod1_len = (fp_unsigned_bin_size(unconst_fp_int(mod1)) + 3) & ~3;
+ const size_t exp2_len = (fp_unsigned_bin_size(unconst_fp_int(exp2)) + 3) & ~3;
+ const size_t mod2_len = (fp_unsigned_bin_size(unconst_fp_int(mod2)) + 3) & ~3;
uint8_t msgbuf[msg_len];
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 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 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
+ };
if ((err = unpack_fp(msg, msgbuf, sizeof(msgbuf))) != HAL_OK ||
(err = unpack_fp(exp1, expbuf1, sizeof(expbuf1))) != HAL_OK ||
@@ -318,7 +341,7 @@ static hal_error_t modexp2(const int precalc,
(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)
- goto fail;
+ goto fail;
fp_read_unsigned_bin(res1, resbuf1, sizeof(resbuf1));
fp_read_unsigned_bin(res2, resbuf2, sizeof(resbuf2));
@@ -415,12 +438,10 @@ int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
#endif /* HAL_RSA_SIGN_USE_MODEXP && HAL_RSA_KEYGEN_USE_MODEXP */
/*
- * Create blinding factors. There are various schemes for amortizing
- * the cost of this over multiple RSA operations, at present we don't
- * try. Come back to this if it looks like a bottleneck.
+ * Create blinding factors.
*/
-static hal_error_t create_blinding_factors(hal_core_t *core, hal_rsa_key_t *key, fp_int *bf, fp_int *ubf)
+static hal_error_t create_blinding_factors(hal_rsa_key_t *key, fp_int *bf, fp_int *ubf)
{
if (key == NULL || bf == NULL || ubf == NULL)
return HAL_ERROR_IMPOSSIBLE;
@@ -429,14 +450,39 @@ static hal_error_t create_blinding_factors(hal_core_t *core, hal_rsa_key_t *key,
uint8_t rnd[fp_unsigned_bin_size(unconst_fp_int(key->n))];
hal_error_t err = HAL_OK;
+ hal_rsa_bf_lock();
+
+#if HAL_RSA_BLINDING_CACHE_SIZE > 0
+ unsigned best_delta = 0;
+ int best_index = 0;
+
+ for (int i = 0; i < HAL_RSA_BLINDING_CACHE_SIZE; i++) {
+ bfc_slot_t *b = &bfc.slot[i];
+ const unsigned delta = bfc.lru - b->lru;
+ if (delta > best_delta) {
+ best_delta = delta;
+ best_index = i;
+ }
+ if (fp_cmp_mag(b->n, key->n) == FP_EQ) {
+ if (fp_sqrmod(b->bf, key->n, b->bf) != FP_OKAY ||
+ fp_sqrmod(b->ubf, key->n, b->ubf) != FP_OKAY)
+ continue; /* should never happen, but be safe */
+ fp_copy(b->bf, bf);
+ fp_copy(b->ubf, ubf);
+ err = HAL_OK;
+ goto fail;
+ }
+ }
+#endif
+
if ((err = hal_get_random(NULL, rnd, sizeof(rnd))) != HAL_OK)
goto fail;
fp_init(bf);
- fp_read_unsigned_bin(bf, rnd, sizeof(rnd));
+ fp_read_unsigned_bin(bf, rnd, sizeof(rnd));
fp_copy(bf, ubf);
- if ((err = modexp(core, precalc, bf, key->e, key->n, bf,
+ 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;
@@ -445,7 +491,18 @@ static hal_error_t create_blinding_factors(hal_core_t *core, hal_rsa_key_t *key,
FP_CHECK(fp_invmod(ubf, unconst_fp_int(key->n), ubf));
+#if HAL_RSA_BLINDING_CACHE_SIZE > 0
+ {
+ bfc_slot_t *b = &bfc.slot[best_index];
+ fp_copy(key->n, b->n);
+ fp_copy(bf, b->bf);
+ fp_copy(ubf, b->ubf);
+ b->lru = ++bfc.lru;
+ }
+#endif
+
fail:
+ hal_rsa_bf_unlock();
memset(rnd, 0, sizeof(rnd));
return err;
}
@@ -471,7 +528,7 @@ static hal_error_t rsa_crt(hal_core_t *core1, hal_core_t *core2, hal_rsa_key_t *
* Handle blinding if requested.
*/
if (blinding) {
- if ((err = create_blinding_factors(core1, key, bf, ubf)) != HAL_OK)
+ if ((err = create_blinding_factors(key, bf, ubf)) != HAL_OK)
goto fail;
FP_CHECK(fp_mulmod(msg, bf, unconst_fp_int(key->n), msg));
}
diff --git a/slip.c b/slip.c
index b53d54c..c4c74bd 100644
--- a/slip.c
+++ b/slip.c
@@ -48,7 +48,7 @@
#if HAL_SLIP_DEBUG
#include <stdio.h>
-#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { printf("%s returned %d (%s)\n", #op, _err_, hal_error_string(_err_)); return _err_; } } while (0)
+#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { hal_log(HAL_LOG_DEBUG, "%s returned %d (%s)", #op, _err_, hal_error_string(_err_)); return _err_; } } while (0)
#else
#define check(op) do { const hal_error_t _err_ = (op); if (_err_ != HAL_OK) { return _err_; } } while (0)
#endif
diff --git a/tests/parallel-signatures.py b/tests/parallel-signatures.py
index 006b753..8d98460 100755
--- a/tests/parallel-signatures.py
+++ b/tests/parallel-signatures.py
@@ -54,7 +54,6 @@ from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
from tornado.gen import Return, coroutine
from tornado.ioloop import IOLoop
from tornado.iostream import IOStream, StreamClosedError
-from tornado.queues import Queue
from Crypto.Util.asn1 import DerSequence, DerNull, DerOctetString
from Crypto.Util.number import inverse
@@ -197,55 +196,52 @@ def pkcs1_hash_and_pad(text):
@coroutine
-def worker(args, k, p, q, r, m):
- while True:
- n = yield q.get()
+def client(args, k, p, q, r, m, v, h):
+ while q:
+ n = q.pop(0)
logger.debug("Signing %s", n)
- try:
- t0 = datetime.datetime.now()
- s = yield p.sign(data = m)
- t1 = datetime.datetime.now()
- if args.verify:
- k.verify(s)
- r.add(t0, t1)
- except:
- logger.exception("Signature failed")
- finally:
- q.task_done()
+ t0 = datetime.datetime.now()
+ s = yield p.sign(data = m)
+ t1 = datetime.datetime.now()
+ logger.debug("Signature %s: %s", n, ":".join("{:02x}".format(ord(b)) for b in s))
+ if args.verify and not v.verify(h, s):
+ raise RuntimeError("RSA verification failed")
+ r.add(t0, t1)
+
@coroutine
def main():
parser = ArgumentParser(description = __doc__, formatter_class = ArgumentDefaultsHelpFormatter)
parser.add_argument("-i", "--iterations", default = 1000, type = int, help = "iterations")
+ parser.add_argument("-c", "--clients", default = 4, type = int, help = "client count")
parser.add_argument("-k", "--key", choices = tuple(key_table),
default = "rsa_2048", help = "key to test")
parser.add_argument("-p", "--pin", default = "fnord", help = "user PIN")
- parser.add_argument("-q", "--quiet", action = "store_true", help = "be less chatty")
+ parser.add_argument("-q", "--quiet", action = "store_true", help = "bark less")
+ parser.add_argument("-d", "--debug", action = "store_true", help = "bark more")
parser.add_argument("-t", "--text", default = "Hamsters'R'Us", help = "plaintext to sign")
parser.add_argument("-v", "--verify", action = "store_true", help = "verify signatures")
- parser.add_argument("-w", "--workers", default = 4, type = int, help = "worker count")
args = parser.parse_args()
+ if args.debug:
+ logging.getLogger().setLevel(logging.DEBUG)
+
k = key_table[args.key]
- q = Queue()
-
- tbs = pkcs1_hash_and_pad(args.text)
- der = k.exportKey(format = "DER", pkcs = 8)
+ d = k.exportKey(format = "DER", pkcs = 8)
+ h = SHA256(args.text)
+ v = PKCS115_SigScheme(k)
+ q = range(args.iterations)
+ m = pkcs1_hash_and_pad(args.text)
+ r = Result(args, args.key)
- hsms = [HSM() for i in xrange(args.workers)]
+ hsms = [HSM() for i in xrange(args.clients)]
for hsm in hsms:
yield hsm.login(HAL_USER_NORMAL, args.pin)
- pkeys = yield [hsm.pkey_load(der, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE) for hsm in hsms]
-
- r = Result(args, args.key)
-
- for pkey in pkeys:
- IOLoop.current().spawn_callback(worker, args, k, pkey, q, r, tbs)
+ pkeys = yield [hsm.pkey_load(d, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE) for hsm in hsms]
- yield [q.put(i) for i in xrange(args.iterations)]
- yield q.join()
+ yield [client(args, k, pkey, q, r, m, v, h) for pkey in pkeys]
yield [pkey.delete() for pkey in pkeys]
@@ -296,6 +292,7 @@ class Result(object):
"mean {0.mean} "
"speedup {0.speedup} "
"(n {0.n}, "
+ "c {0.args.clients} "
"t0 {0.t0} "
"t1 {0.t1})\n").format(self))
sys.stdout.flush()
diff --git a/tests/test-rsa.c b/tests/test-rsa.c
index 176ba03..853f90f 100644
--- a/tests/test-rsa.c
+++ b/tests/test-rsa.c
@@ -49,8 +49,7 @@
* Run one modexp test.
*/
-static int test_modexp(hal_core_t *core,
- const char * const kind,
+static int test_modexp(const char * const kind,
const rsa_tc_t * const tc,
const rsa_tc_bn_t * const msg, /* Input message */
const rsa_tc_bn_t * const exp, /* Exponent */
@@ -61,7 +60,6 @@ static int test_modexp(hal_core_t *core,
printf("%s test for %lu-bit RSA key\n", kind, (unsigned long) tc->size);
hal_modexp_arg_t args = {
- .core = core,
.msg = msg->val, .msg_len = msg->len,
.exp = exp->val, .exp_len = exp->len,
.mod = tc->n.val, .mod_len = tc->n.len,
@@ -83,8 +81,7 @@ static int test_modexp(hal_core_t *core,
* Run one RSA CRT test.
*/
-static int test_decrypt(hal_core_t *core,
- const char * const kind,
+static int test_decrypt(const char * const kind,
const rsa_tc_t * const tc)
{
printf("%s test for %lu-bit RSA key\n", kind, (unsigned long) tc->size);
@@ -107,7 +104,7 @@ static int test_decrypt(hal_core_t *core,
uint8_t result[tc->n.len];
- if ((err = hal_rsa_decrypt(core, NULL, key, tc->m.val, tc->m.len, result, sizeof(result))) != HAL_OK)
+ if ((err = hal_rsa_decrypt(NULL, NULL, key, tc->m.val, tc->m.len, result, sizeof(result))) != HAL_OK)
printf("RSA CRT failed: %s\n", hal_error_string(err));
const int mismatch = (err == HAL_OK && memcmp(result, tc->s.val, tc->s.len) != 0);
@@ -124,8 +121,7 @@ static int test_decrypt(hal_core_t *core,
* Run one RSA key generation + CRT test.
*/
-static int test_gen(hal_core_t *core,
- const char * const kind,
+static int test_gen(const char * const kind,
const rsa_tc_t * const tc)
{
printf("%s test for %lu-bit RSA key\n", kind, (unsigned long) tc->size);
@@ -138,7 +134,7 @@ static int test_gen(hal_core_t *core,
const uint8_t f4[] = { 0x01, 0x00, 0x01 };
- if ((err = hal_rsa_key_gen(core, &key1, keybuf1, sizeof(keybuf1), bitsToBytes(tc->size), f4, sizeof(f4))) != HAL_OK)
+ if ((err = hal_rsa_key_gen(NULL, &key1, keybuf1, sizeof(keybuf1), bitsToBytes(tc->size), f4, sizeof(f4))) != HAL_OK)
return printf("RSA key generation failed: %s\n", hal_error_string(err)), 0;
size_t der_len = 0;
@@ -174,7 +170,7 @@ static int test_gen(hal_core_t *core,
uint8_t result[tc->n.len];
- if ((err = hal_rsa_decrypt(core, NULL, key1, tc->m.val, tc->m.len, result, sizeof(result))) != HAL_OK)
+ if ((err = hal_rsa_decrypt(NULL, NULL, key1, tc->m.val, tc->m.len, result, sizeof(result))) != HAL_OK)
printf("RSA CRT failed: %s\n", hal_error_string(err));
snprintf(fn, sizeof(fn), "test-rsa-sig-%04lu.der", (unsigned long) tc->size);
@@ -192,7 +188,7 @@ static int test_gen(hal_core_t *core,
if (err != HAL_OK) /* Deferred failure from hal_rsa_decrypt(), above */
return 0;
- if ((err = hal_rsa_encrypt(core, key1, result, sizeof(result), result, sizeof(result))) != HAL_OK)
+ if ((err = hal_rsa_encrypt(NULL, key1, result, sizeof(result), result, sizeof(result))) != HAL_OK)
printf("First RSA signature check failed: %s\n", hal_error_string(err));
int mismatch = 0;
@@ -239,7 +235,7 @@ static int test_gen(hal_core_t *core,
* the public key passes the signature verification test below.
*/
- if ((err = hal_rsa_encrypt(core, key2, result, sizeof(result), result, sizeof(result))) != HAL_OK)
+ if ((err = hal_rsa_encrypt(NULL, key2, result, sizeof(result), result, sizeof(result))) != HAL_OK)
return printf("Second RSA signature check failed: %s\n", hal_error_string(err)), 0;
if (err == HAL_OK && memcmp(result, tc->m.val, tc->m.len) != 0)
@@ -286,34 +282,31 @@ static void _time_check(const struct timeval t0, const int ok)
* and try generating a signature with that.
*/
-static int test_rsa(hal_core_t *core, const rsa_tc_t * const tc)
+static int test_rsa(const rsa_tc_t * const tc)
{
int ok = 1;
/* RSA encryption */
- time_check(test_modexp(core, "Verification", tc, &tc->s, &tc->e, &tc->m));
+ time_check(test_modexp("Verification", tc, &tc->s, &tc->e, &tc->m));
/* Brute force RSA decryption */
- time_check(test_modexp(core, "Signature (ModExp)", tc, &tc->m, &tc->d, &tc->s));
+ time_check(test_modexp("Signature (ModExp)", tc, &tc->m, &tc->d, &tc->s));
/* RSA decyrption using CRT */
- time_check(test_decrypt(core, "Signature (CRT)", tc));
+ time_check(test_decrypt("Signature (CRT)", tc));
/* Key generation and CRT -- not test vector, so writes key and sig to file */
- time_check(test_gen(core, "Generation and CRT", tc));
+ time_check(test_gen("Generation and CRT", tc));
return ok;
}
int main(void)
{
- hal_core_t *core = hal_core_find(MODEXPS6_NAME, NULL);
- if (core == NULL)
- core = hal_core_find(MODEXPA7_NAME, NULL);
- const hal_core_info_t *core_info = hal_core_info(core);
+ const hal_core_info_t *info = hal_core_info(hal_core_find(MODEXPA7_NAME, NULL));
- if (core_info != NULL)
- printf("\"%8.8s\" \"%4.4s\"\n\n", core_info->name, core_info->version);
+ if (info != NULL)
+ printf("\"%8.8s\" \"%4.4s\"\n\n", info->name, info->version);
/*
* Run the test cases.
@@ -324,7 +317,7 @@ int main(void)
/* Normal test */
for (size_t i = 0; i < (sizeof(rsa_tc)/sizeof(*rsa_tc)); i++)
- if (!test_rsa(core, &rsa_tc[i]))
+ if (!test_rsa(&rsa_tc[i]))
return 1;
return 0;
diff --git a/uuid.c b/uuid.c
index 8b82066..0a4d2d1 100644
--- a/uuid.c
+++ b/uuid.c
@@ -33,7 +33,6 @@
*/
#include <stdio.h>
-#include <assert.h>
#include "hal.h"
#include "hal_internal.h"