[Cryptech-Commits] [sw/libhal] 02/02: First cut at libhal support for hash cores with ability to save and restore internal state. Compiles, not yet tested.

git at cryptech.is git at cryptech.is
Fri Jul 17 08:57:16 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 19e0714efb5b21033a759bb7b75ce1b8a1a06b83
Author: Rob Austein <sra at hactrn.net>
Date:   Fri Jul 17 10:54:52 2015 +0200

    First cut at libhal support for hash cores with ability to save and
    restore internal state.  Compiles, not yet tested.
---
 hal.h  |   1 +
 hash.c | 100 +++++++++++++++++++++++++++++++++++++++++++----------------------
 2 files changed, 68 insertions(+), 33 deletions(-)

diff --git a/hal.h b/hal.h
index 4a31398..ab4e9c1 100644
--- a/hal.h
+++ b/hal.h
@@ -511,6 +511,7 @@ typedef struct {
   const uint8_t * const digest_algorithm_id;
   size_t digest_algorithm_id_length;
   const void *driver;
+  unsigned can_restore_state : 1;
 } hal_hash_descriptor_t;
 
 /*
diff --git a/hash.c b/hash.c
index f48e079..af461a6 100644
--- a/hash.c
+++ b/hash.c
@@ -76,7 +76,8 @@ typedef struct {
 } driver_t;
 
 /*
- * Hash state.
+ * Hash state.  For now we assume that the only core state we need to
+ * save and restore is the current digest value.
  */
 
 typedef struct {
@@ -84,7 +85,8 @@ typedef struct {
   const driver_t *driver;
   uint64_t msg_length_high;                     /* Total data hashed in this message */
   uint64_t msg_length_low;                      /* (128 bits in SHA-512 cases) */
-  uint8_t block[HAL_MAX_HASH_BLOCK_LENGTH];     /* Block we're accumulating */
+  uint8_t block[HAL_MAX_HASH_BLOCK_LENGTH],     /* Block we're accumulating */
+    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 */
 } internal_hash_state_t;
@@ -185,42 +187,42 @@ const hal_hash_descriptor_t hal_hash_sha1[1] = {{
   SHA1_BLOCK_LEN, SHA1_DIGEST_LEN,
   sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t),
   dalgid_sha1, sizeof(dalgid_sha1),
-  &sha1_driver
+  &sha1_driver, 0
 }};
 
 const hal_hash_descriptor_t hal_hash_sha256[1] = {{
   SHA256_BLOCK_LEN, SHA256_DIGEST_LEN,
   sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t),
   dalgid_sha256, sizeof(dalgid_sha256),
-  &sha256_driver
+  &sha256_driver, 1
 }};
 
 const hal_hash_descriptor_t hal_hash_sha512_224[1] = {{
   SHA512_BLOCK_LEN, SHA512_224_DIGEST_LEN,
   sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t),
   dalgid_sha512_224, sizeof(dalgid_sha512_224),
-  &sha512_224_driver
+  &sha512_224_driver, 0
 }};
 
 const hal_hash_descriptor_t hal_hash_sha512_256[1] = {{
   SHA512_BLOCK_LEN, SHA512_256_DIGEST_LEN,
   sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t),
   dalgid_sha512_256, sizeof(dalgid_sha512_256),
-  &sha512_256_driver
+  &sha512_256_driver, 0
 }};
 
 const hal_hash_descriptor_t hal_hash_sha384[1] = {{
   SHA512_BLOCK_LEN, SHA384_DIGEST_LEN,
   sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t),
   dalgid_sha384, sizeof(dalgid_sha384),
-  &sha384_driver
+  &sha384_driver, 0
 }};
 
 const hal_hash_descriptor_t hal_hash_sha512[1] = {{
   SHA512_BLOCK_LEN, SHA512_DIGEST_LEN,
   sizeof(internal_hash_state_t), sizeof(internal_hmac_state_t),
   dalgid_sha512, sizeof(dalgid_sha512),
-  &sha512_driver
+  &sha512_driver, 0
 }};
 
 /*
@@ -281,17 +283,54 @@ hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor,
   memset(state, 0, sizeof(*state));
   state->descriptor = descriptor;
   state->driver = driver;
-
+    
   opaque_state->state = state;
 
   return HAL_OK;
 }
 
 /*
+ * Read hash result from core.  At least for now, this also serves to
+ * read current hash state from core.
+ */
+
+static hal_error_t hash_read_digest(const driver_t * const driver,
+                                    uint8_t *digest,
+                                    const size_t digest_length)
+{
+  hal_error_t err;
+
+  assert(digest != NULL && digest_length % 4 == 0);
+
+  if ((err = hal_io_wait_valid(driver->status_addr)) != HAL_OK)
+    return err;
+
+  return hal_io_read(driver->digest_addr, digest, digest_length);
+}
+
+/*
+ * Write hash state back to core.
+ */
+
+static hal_error_t hash_write_digest(const driver_t * const driver,
+                                     const uint8_t * const digest,
+                                     const size_t digest_length)
+{
+  hal_error_t err;
+
+  assert(digest != NULL && digest_length % 4 == 0);
+
+  if ((err = hal_io_wait_ready(driver->status_addr)) != HAL_OK)
+    return err;
+
+  return hal_io_write(driver->digest_addr, digest, digest_length);
+}
+
+/*
  * Send one block to a core.
  */
 
-static hal_error_t hash_write_block(const internal_hash_state_t * const state)
+static hal_error_t hash_write_block(internal_hash_state_t *state)
 {
   uint8_t ctrl_cmd[4];
   hal_error_t err;
@@ -299,43 +338,38 @@ static hal_error_t hash_write_block(const internal_hash_state_t * const state)
   assert(state != NULL && state->descriptor != NULL && state->driver != NULL);
   assert(state->descriptor->block_length % 4 == 0);
 
+  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");
 
-  if ((err = hal_io_write(state->driver->block_addr, state->block, state->descriptor->block_length)) != HAL_OK)
+  if ((err = hal_io_wait_ready(state->driver->status_addr)) != HAL_OK)
+    return err;
+
+  if (state->descriptor->can_restore_state &&
+      state->block_count != 0 &&
+      (err = hash_write_digest(state->driver, state->core_state,
+                               state->descriptor->digest_length)) != HAL_OK)
+    return err;
+
+  if ((err = hal_io_write(state->driver->block_addr, state->block,
+                          state->descriptor->block_length)) != HAL_OK)
     return err;
 
   ctrl_cmd[0] = ctrl_cmd[1] = ctrl_cmd[2] = 0;
   ctrl_cmd[3] = state->block_count == 0 ? CTRL_INIT : CTRL_NEXT;  
   ctrl_cmd[3] |= state->driver->ctrl_mode;
 
-  /*
-   * Not sure why we're waiting for ready here, but it's what the old
-   * (read: tested) code did, so keep that behavior for now.
-   */
-
   if ((err = hal_io_write(state->driver->ctrl_addr, ctrl_cmd, sizeof(ctrl_cmd))) != HAL_OK)
     return err;
 
-  return hal_io_wait_valid(state->driver->status_addr);
-}
-
-/*
- * Read hash result from core.
- */
-
-static hal_error_t hash_read_digest(const driver_t * const driver,
-                                    uint8_t *digest,
-                                    const size_t digest_length)
-{
-  hal_error_t err;
-
-  assert(digest != NULL && digest_length % 4 == 0);
-
-  if ((err = hal_io_wait_valid(driver->status_addr)) != HAL_OK)
+  if (state->descriptor->can_restore_state &&
+      (err = hash_read_digest(state->driver, state->core_state,
+                              state->descriptor->digest_length)) != HAL_OK)
     return err;
 
-  return hal_io_read(driver->digest_addr, digest, digest_length);
+  return hal_io_wait_valid(state->driver->status_addr);
 }
 
 /*



More information about the Commits mailing list