[Cryptech-Commits] [sw/libhal] 01/01: Add support for dynamic allocation of hash and HMAC state, for cases where it's unavoidable.

git at cryptech.is git at cryptech.is
Sat Jul 18 09:04:06 UTC 2015


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

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

commit 809f0c7e9a4c49aa52b77ec2ab58a970a3ade389
Author: Rob Austein <sra at hactrn.net>
Date:   Sat Jul 18 10:58:45 2015 +0200

    Add support for dynamic allocation of hash and HMAC state, for cases
    where it's unavoidable.
---
 hal.h  |  3 +++
 hash.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/hal.h b/hal.h
index 15ab8f9..7aeed42 100644
--- a/hal.h
+++ b/hal.h
@@ -567,6 +567,9 @@ extern hal_error_t hal_hmac_update(const hal_hmac_state_t state,
 
 extern hal_error_t hal_hmac_finalize(const hal_hmac_state_t state,
                                      uint8_t *hmac, const size_t length);
+extern void hal_hash_cleanup(hal_hash_state_t *state);
+
+extern void hal_hmac_cleanup(hal_hmac_state_t *state);
 
 /*
  * AES key wrap functions.
diff --git a/hash.c b/hash.c
index af461a6..45e2f59 100644
--- a/hash.c
+++ b/hash.c
@@ -89,8 +89,11 @@ typedef struct {
     core_state[HAL_MAX_HASH_DIGEST_LENGTH];     /* Saved core state */
   size_t block_used;                            /* How much of the block we've used */
   unsigned block_count;                         /* Blocks sent */
+  unsigned flags;
 } internal_hash_state_t;
 
+#define STATE_FLAG_STATE_ALLOCATED 0x1          /* State buffer dynamically allocated */
+
 /*
  * HMAC state.  Right now this just holds the key block and a hash
  * context; if and when we figure out how PCLSR the hash cores, we
@@ -276,20 +279,47 @@ hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor,
   const driver_t * const driver = check_driver(descriptor);
   internal_hash_state_t *state = state_buffer;
 
-  if (driver == NULL || state == NULL || opaque_state == NULL ||
-      state_length < descriptor->hash_state_length)
+  if (driver == NULL || opaque_state == NULL)
+    return HAL_ERROR_BAD_ARGUMENTS;
+
+  if (state_buffer != NULL && state_length < descriptor->hash_state_length)
     return HAL_ERROR_BAD_ARGUMENTS;
 
+  if (state_buffer == NULL && (state = malloc(descriptor->hash_state_length)) == NULL)
+      return HAL_ERROR_ALLOCATION_FAILURE;
+
   memset(state, 0, sizeof(*state));
   state->descriptor = descriptor;
   state->driver = driver;
     
+  if (state_buffer == NULL)
+    state->flags |= STATE_FLAG_STATE_ALLOCATED;
+
   opaque_state->state = state;
 
   return HAL_OK;
 }
 
 /*
+ * Clean up hash state.  No-op unless memory was dynamically allocated.
+ */
+
+void hal_hash_cleanup(hal_hash_state_t *opaque_state)
+{
+  if (opaque_state == NULL)
+    return;
+
+  internal_hash_state_t *state = opaque_state->state;
+
+  if (state == NULL || (state->flags & STATE_FLAG_STATE_ALLOCATED) == 0)
+    return;
+
+  memset(state, 0, state->descriptor->hash_state_length);
+  free(state);
+  opaque_state->state = NULL;
+}
+
+/*
  * Read hash result from core.  At least for now, this also serves to
  * read current hash state from core.
  */
@@ -519,15 +549,21 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
 {
   const driver_t * const driver = check_driver(descriptor);
   internal_hmac_state_t *state = state_buffer;
-  internal_hash_state_t *h = &state->hash_state;
   hal_hash_state_t oh;
   hal_error_t err;
   int i;
 
-  if (descriptor == NULL || driver == NULL || state == NULL || opaque_state == NULL ||
-      state_length < descriptor->hmac_state_length)
+  if (driver == NULL || opaque_state == NULL)
     return HAL_ERROR_BAD_ARGUMENTS;
 
+  if (state_buffer != NULL && state_length < descriptor->hmac_state_length)
+    return HAL_ERROR_BAD_ARGUMENTS;
+
+  if (state_buffer == NULL && (state = malloc(descriptor->hmac_state_length)) == NULL)
+    return HAL_ERROR_ALLOCATION_FAILURE;
+
+  internal_hash_state_t *h = &state->hash_state;
+
   assert(descriptor->block_length <= sizeof(state->keybuf));
 
 #if 0
@@ -541,7 +577,10 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
 #endif
 
   if ((err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK)
-    return err;
+    goto fail;
+
+  if (state_buffer == NULL)
+    h->flags |= STATE_FLAG_STATE_ALLOCATED;
 
   /*
    * If the supplied HMAC key is longer than the hash block length, we
@@ -557,7 +596,7 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
   else if ((err = hal_hash_update(oh, key, key_length))                        != HAL_OK ||
            (err = hal_hash_finalize(oh, state->keybuf, sizeof(state->keybuf))) != HAL_OK ||
            (err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h)))         != HAL_OK)
-    return err;
+    goto fail;
 
   /*
    * XOR the key with the IPAD value, then start the inner hash.
@@ -567,7 +606,7 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
     state->keybuf[i] ^= HMAC_IPAD;
 
   if ((err = hal_hash_update(oh, state->keybuf, descriptor->block_length)) != HAL_OK)
-    return err;
+    goto fail;
 
   /*
    * Prepare the key for the final hash.  Since we just XORed key with
@@ -588,6 +627,35 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
   opaque_state->state = state;
 
   return HAL_OK;
+
+ fail:
+  if (state_buffer == NULL)
+    free(state);
+  return err;
+}
+
+/*
+ * Clean up HMAC state.  No-op unless memory was dynamically allocated.
+ */
+
+void hal_hmac_cleanup(hal_hmac_state_t *opaque_state)
+{
+  if (opaque_state == NULL)
+    return;
+
+  internal_hmac_state_t *state = opaque_state->state;
+
+  if (state == NULL)
+    return;
+
+  internal_hash_state_t *h = &state->hash_state;
+
+  if ((h->flags & STATE_FLAG_STATE_ALLOCATED) == 0)
+    return;
+
+  memset(state, 0, h->descriptor->hmac_state_length);
+  free(state);
+  opaque_state->state = NULL;
 }
 
 /*



More information about the Commits mailing list