[Cryptech-Commits] [sw/libhal] 02/03: Better hal_core_alloc() semantics, assert() and printf() cleanup.

git at cryptech.is git at cryptech.is
Sun May 20 23:47:07 UTC 2018


This is an automated email from the git hooks/post-receive script.

sra at hactrn.net pushed a commit to branch master
in repository sw/libhal.

commit e6bdf57820121b6eac9f35c8ef53a4e7a76205e1
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Sun May 20 18:18:40 2018 -0400

    Better hal_core_alloc() semantics, assert() and printf() cleanup.
    
    Various fixes extracted from the abandoned(-for-now?) reuse-cores
    branch, principally:
    
    * Change hal_core_alloc*() to support core reuse and to pick the
      least-recently-used core of a particular type otherwise;
    
    * Replace assert() and printf() calls with hal_assert() and hal_log(),
      respectively.  assert() is particularly useless on the HSM, since it
      sends its error message into hyperspace then hangs the HSM.
---
 aes_keywrap.c    |  18 +++--
 asn1.c           |  16 ++--
 core.c           | 220 ++++++++++++++++++++++++++++-------------------------
 csprng.c         |   8 +-
 ecdsa.c          |  70 +++++++++--------
 hal.h            |  15 ++--
 hal_internal.h   |  24 +++---
 hash.c           | 226 +++++++++++++++++++++++++++++--------------------------
 mkmif.c          |  38 +++++++---
 modexp.c         |  57 +++++++++-----
 pbkdf2.c         |   8 +-
 rpc_client.c     |   6 +-
 rpc_pkcs1.c      |   6 +-
 rpc_pkey.c       |  44 ++++++-----
 rpc_serial.c     |   2 +-
 rsa.c            |  86 +++++++++++----------
 slip.c           |   2 +-
 tests/test-rsa.c |  41 +++++-----
 18 files changed, 477 insertions(+), 410 deletions(-)

diff --git a/aes_keywrap.c b/aes_keywrap.c
index 355cb0b..be082f6 100644
--- a/aes_keywrap.c
+++ b/aes_keywrap.c
@@ -132,7 +132,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 +164,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 +216,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 +228,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 +243,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 +297,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 a653b45..1ead2e7 100644
--- a/asn1.c
+++ b/asn1.c
@@ -164,7 +164,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)
@@ -250,8 +250,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;
 }
@@ -342,8 +342,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;
 }
@@ -410,8 +410,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;
 }
@@ -427,7 +427,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..10f624d 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,31 @@ 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 (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
-
-  for (hal_addr_t addr = CORE_MIN; addr < CORE_MAX; addr += CORE_SIZE) {
+  hal_addr_t addr;
+  int n;
 
-#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 +135,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 +163,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 (;;) {
 
-  while (1) {
-    if ((err = hal_core_alloc(name1, pcore1)) != HAL_OK)
+    hal_error_t err = hal_core_alloc_no_wait(name1, pcore1, pomace1);
+
+    switch (err) {
+
+    case HAL_OK:
+      break;
+
+    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)
@@ -293,11 +312,6 @@ 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/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 28cfa02..c92dfbf 100644
--- a/ecdsa.c
+++ b/ecdsa.c
@@ -354,8 +354,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 +366,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 +381,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 +404,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 +432,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 +476,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 +521,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 +545,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 +643,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 +663,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;
@@ -786,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];
@@ -797,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)
@@ -845,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
@@ -932,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;
@@ -965,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.
  */
@@ -1171,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;
@@ -1184,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);
@@ -1197,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;
 }
@@ -1290,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);
@@ -1465,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);
@@ -1479,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,
@@ -1553,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));
@@ -1588,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;
@@ -1694,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 a614335..601f282 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")                             \
   END_OF_HAL_ERROR_LIST
 
 /* Marker to forestall silly line continuation errors */
@@ -220,18 +222,17 @@ typedef struct {
   hal_addr_t base;
 } hal_core_info_t;
 
+typedef uint32_t hal_core_lru_t;
+
 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_alloc2(const char *name1, hal_core_t **pcore1,
-                                   const char *name2, hal_core_t **pcore2);
+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 922562a..742b67b 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -47,6 +47,19 @@
  * should be looking at this file.
  */
 
+/*
+ * 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 is not available in arm-none-eabi headers or libc.
  */
@@ -513,15 +526,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/hash.c b/hash.c
index d1e55ff..59ca88a 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
@@ -119,10 +119,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 +332,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 +340,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 +367,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;
 
-    *core = NULL;
+  if ((err = hal_core_alloc(descriptor->core_name, core, pomace)) == HAL_OK) {
+    *flags |= STATE_FLAG_FREE_CORE;
+    return HAL_OK;
+  }
+
+#endif
 
-    if (flags != NULL)
-      *flags |= STATE_FLAG_SOFTWARE_CORE;
+  if (*core != NULL)
+    return HAL_ERROR_IMPOSSIBLE;
 
-    err = HAL_OK;
+#if HAL_ENABLE_SOFTWARE_HASH_CORES
+
+  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 +426,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 +436,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 (!state->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 +454,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 +462,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_;
-
-  if (state == NULL || (state->flags & STATE_FLAG_STATE_ALLOCATED) == 0)
-    return;
+  memset(*state, 0, (*state)->descriptor->hash_state_length);
 
-  memset(state, 0, state->descriptor->hash_state_length);
-  *state_ = NULL;
+  *state = NULL;
 }
 
 #if ! HAL_ONLY_USE_SOFTWARE_HASH_CORES
@@ -482,7 +489,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 +508,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 +524,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 +592,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 +628,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 +638,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 +660,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 +685,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 +703,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 +726,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 +736,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 +767,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 +837,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)
-    return;
-
-  hal_hmac_state_t *state = *state_;
-
-  if (state == NULL)
+  if (state == NULL || *state == NULL)
     return;
 
-  hal_hash_state_t *h = &state->hash_state;
+  memset(*state, 0, (*state)->hash_state.descriptor->hmac_state_length);
 
-  if ((h->flags & STATE_FLAG_STATE_ALLOCATED) == 0)
-    return;
-
-  memset(state, 0, h->descriptor->hmac_state_length);
-  *state_ = NULL;
+  *state = NULL;
 }
 
 /*
@@ -878,15 +878,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 +975,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 +1003,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 +1013,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 +1025,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 +1041,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 +1049,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 +1072,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 +1089,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 +1132,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 +1151,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/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 0a1e57e..607a0fb 100644
--- a/pbkdf2.c
+++ b/pbkdf2.c
@@ -53,7 +53,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 +96,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 e968369..13ea265 100644
--- a/rpc_client.c
+++ b/rpc_client.c
@@ -45,7 +45,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
@@ -73,14 +73,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..96bd296 100644
--- a/rpc_pkcs1.c
+++ b/rpc_pkcs1.c
@@ -46,7 +46,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 +62,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 +76,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 294a3e5..c1cefea 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -73,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;
 
@@ -224,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;
@@ -260,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;
 
@@ -330,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;
@@ -374,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;
@@ -418,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;
@@ -477,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;
@@ -738,18 +736,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;
@@ -760,7 +758,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;
 
@@ -787,8 +785,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;
@@ -879,8 +877,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:
@@ -926,8 +924,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:
@@ -1057,7 +1055,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;
@@ -1142,7 +1140,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;
@@ -1239,7 +1237,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 8b55c93..1b5de7d 100644
--- a/rsa.c
+++ b/rsa.c
@@ -238,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)
 {
@@ -248,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));
 
@@ -306,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 ||
@@ -341,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));
@@ -438,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;
@@ -481,10 +479,10 @@ static hal_error_t create_blinding_factors(hal_core_t *core, hal_rsa_key_t *key,
     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;
 
@@ -530,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/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;



More information about the Commits mailing list