aboutsummaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c195
1 files changed, 94 insertions, 101 deletions
diff --git a/hash.c b/hash.c
index 45e2f59..e06278d 100644
--- a/hash.c
+++ b/hash.c
@@ -1,34 +1,34 @@
-/*
+/*
* hashes.c
* --------
* HAL interface to Cryptech hash cores.
- *
+ *
* Authors: Joachim Strömbergson, Paul Selkirk, Rob Austein
* Copyright (c) 2014-2015, SUNET
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -64,7 +64,7 @@
* memory map, so it's not really worth overthinking at the moment.
*/
-typedef struct {
+struct hal_hash_driver {
size_t length_length; /* Length of the length field */
off_t block_addr; /* Where to write hash blocks */
off_t ctrl_addr; /* Control register */
@@ -73,16 +73,16 @@ typedef struct {
off_t name_addr; /* Where to read core name */
char core_name[8]; /* Expected name of core */
uint8_t ctrl_mode; /* Digest mode, for cores that have modes */
-} driver_t;
+};
/*
* Hash state. For now we assume that the only core state we need to
* save and restore is the current digest value.
*/
-typedef struct {
+struct hal_hash_state {
const hal_hash_descriptor_t *descriptor;
- const driver_t *driver;
+ const hal_hash_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 */
@@ -90,7 +90,7 @@ typedef struct {
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 */
@@ -102,10 +102,10 @@ typedef struct {
* performance boost for things like PBKDF2.
*/
-typedef struct {
- internal_hash_state_t hash_state; /* Hash state */
+struct hal_hmac_state {
+ hal_hash_state_t hash_state; /* Hash state */
uint8_t keybuf[HAL_MAX_HASH_BLOCK_LENGTH]; /* HMAC key */
-} internal_hmac_state_t;
+};
/*
* Drivers for known digest algorithms.
@@ -115,42 +115,42 @@ typedef struct {
* whine if the resulting string doesn't fit into the field.
*/
-static const driver_t sha1_driver = {
+static const hal_hash_driver_t sha1_driver = {
SHA1_LENGTH_LEN,
SHA1_ADDR_BLOCK, SHA1_ADDR_CTRL, SHA1_ADDR_STATUS, SHA1_ADDR_DIGEST,
SHA1_ADDR_NAME0, (SHA1_NAME0 SHA1_NAME1),
0
};
-static const driver_t sha256_driver = {
+static const hal_hash_driver_t sha256_driver = {
SHA256_LENGTH_LEN,
SHA256_ADDR_BLOCK, SHA256_ADDR_CTRL, SHA256_ADDR_STATUS, SHA256_ADDR_DIGEST,
SHA256_ADDR_NAME0, (SHA256_NAME0 SHA256_NAME1),
0
};
-static const driver_t sha512_224_driver = {
+static const hal_hash_driver_t sha512_224_driver = {
SHA512_LENGTH_LEN,
SHA512_ADDR_BLOCK, SHA512_ADDR_CTRL, SHA512_ADDR_STATUS, SHA512_ADDR_DIGEST,
SHA512_ADDR_NAME0, (SHA512_NAME0 SHA512_NAME1),
MODE_SHA_512_224
};
-static const driver_t sha512_256_driver = {
+static const hal_hash_driver_t sha512_256_driver = {
SHA512_LENGTH_LEN,
SHA512_ADDR_BLOCK, SHA512_ADDR_CTRL, SHA512_ADDR_STATUS, SHA512_ADDR_DIGEST,
SHA512_ADDR_NAME0, (SHA512_NAME0 SHA512_NAME1),
MODE_SHA_512_256
};
-static const driver_t sha384_driver = {
+static const hal_hash_driver_t sha384_driver = {
SHA512_LENGTH_LEN,
SHA512_ADDR_BLOCK, SHA512_ADDR_CTRL, SHA512_ADDR_STATUS, SHA512_ADDR_DIGEST,
SHA512_ADDR_NAME0, (SHA512_NAME0 SHA512_NAME1),
MODE_SHA_384
};
-static const driver_t sha512_driver = {
+static const hal_hash_driver_t sha512_driver = {
SHA512_LENGTH_LEN,
SHA512_ADDR_BLOCK, SHA512_ADDR_CTRL, SHA512_ADDR_STATUS, SHA512_ADDR_DIGEST,
SHA512_ADDR_NAME0, (SHA512_NAME0 SHA512_NAME1),
@@ -188,42 +188,42 @@ static const uint8_t
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),
+ sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha1, sizeof(dalgid_sha1),
&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),
+ sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha256, sizeof(dalgid_sha256),
&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),
+ sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha512_224, sizeof(dalgid_sha512_224),
&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),
+ sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha512_256, sizeof(dalgid_sha512_256),
&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),
+ sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha384, sizeof(dalgid_sha384),
&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),
+ sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha512, sizeof(dalgid_sha512),
&sha512_driver, 0
}};
@@ -247,7 +247,7 @@ void hal_hash_set_debug(int onoff)
* Returns the driver pointer on success, NULL on failure.
*/
-static const driver_t *check_driver(const hal_hash_descriptor_t * const descriptor)
+static const hal_hash_driver_t *check_driver(const hal_hash_descriptor_t * const descriptor)
{
return descriptor == NULL ? NULL : descriptor->driver;
}
@@ -258,7 +258,7 @@ static const driver_t *check_driver(const hal_hash_descriptor_t * const descript
hal_error_t hal_hash_core_present(const hal_hash_descriptor_t * const descriptor)
{
- const driver_t * const driver = check_driver(descriptor);
+ const hal_hash_driver_t * const driver = check_driver(descriptor);
if (driver == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
@@ -273,13 +273,13 @@ hal_error_t hal_hash_core_present(const hal_hash_descriptor_t * const descriptor
*/
hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor,
- hal_hash_state_t *opaque_state,
+ hal_hash_state_t **state_,
void *state_buffer, const size_t state_length)
{
- const driver_t * const driver = check_driver(descriptor);
- internal_hash_state_t *state = state_buffer;
+ const hal_hash_driver_t * const driver = check_driver(descriptor);
+ hal_hash_state_t *state = state_buffer;
- if (driver == NULL || opaque_state == NULL)
+ if (driver == NULL || state_ == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
if (state_buffer != NULL && state_length < descriptor->hash_state_length)
@@ -295,7 +295,7 @@ hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor,
if (state_buffer == NULL)
state->flags |= STATE_FLAG_STATE_ALLOCATED;
- opaque_state->state = state;
+ *state_ = state;
return HAL_OK;
}
@@ -304,19 +304,19 @@ hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor,
* Clean up hash state. No-op unless memory was dynamically allocated.
*/
-void hal_hash_cleanup(hal_hash_state_t *opaque_state)
+void hal_hash_cleanup(hal_hash_state_t **state_)
{
- if (opaque_state == NULL)
+ if (state_ == NULL)
return;
- internal_hash_state_t *state = opaque_state->state;
+ 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);
free(state);
- opaque_state->state = NULL;
+ *state_ = NULL;
}
/*
@@ -324,7 +324,7 @@ void hal_hash_cleanup(hal_hash_state_t *opaque_state)
* read current hash state from core.
*/
-static hal_error_t hash_read_digest(const driver_t * const driver,
+static hal_error_t hash_read_digest(const hal_hash_driver_t * const driver,
uint8_t *digest,
const size_t digest_length)
{
@@ -342,7 +342,7 @@ static hal_error_t hash_read_digest(const driver_t * const driver,
* Write hash state back to core.
*/
-static hal_error_t hash_write_digest(const driver_t * const driver,
+static hal_error_t hash_write_digest(const hal_hash_driver_t * const driver,
const uint8_t * const digest,
const size_t digest_length)
{
@@ -360,7 +360,7 @@ static hal_error_t hash_write_digest(const driver_t * const driver,
* Send one block to a core.
*/
-static hal_error_t hash_write_block(internal_hash_state_t *state)
+static hal_error_t hash_write_block(hal_hash_state_t * const state)
{
uint8_t ctrl_cmd[4];
hal_error_t err;
@@ -388,7 +388,7 @@ static hal_error_t hash_write_block(internal_hash_state_t *state)
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->block_count == 0 ? CTRL_INIT : CTRL_NEXT;
ctrl_cmd[3] |= state->driver->ctrl_mode;
if ((err = hal_io_write(state->driver->ctrl_addr, ctrl_cmd, sizeof(ctrl_cmd))) != HAL_OK)
@@ -406,11 +406,10 @@ static hal_error_t hash_write_block(internal_hash_state_t *state)
* Add data to hash.
*/
-hal_error_t hal_hash_update(hal_hash_state_t opaque_state, /* Opaque state block */
+hal_error_t hal_hash_update(hal_hash_state_t *state, /* Opaque state block */
const uint8_t * const data_buffer, /* Data to be hashed */
size_t data_buffer_length) /* Length of data_buffer */
{
- internal_hash_state_t *state = opaque_state.state;
const uint8_t *p = data_buffer;
hal_error_t err;
size_t n;
@@ -463,11 +462,10 @@ hal_error_t hal_hash_update(hal_hash_state_t opaque_state, /* Opaque state
* Finish hash and return digest.
*/
-hal_error_t hal_hash_finalize(hal_hash_state_t opaque_state, /* Opaque state block */
+hal_error_t hal_hash_finalize(hal_hash_state_t *state, /* Opaque state block */
uint8_t *digest_buffer, /* Returned digest */
const size_t digest_buffer_length) /* Length of digest_buffer */
{
- internal_hash_state_t *state = opaque_state.state;
uint64_t bit_length_high, bit_length_low;
hal_error_t err;
uint8_t *p;
@@ -543,17 +541,16 @@ hal_error_t hal_hash_finalize(hal_hash_state_t opaque_state, /* Opaqu
*/
hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
- hal_hmac_state_t *opaque_state,
+ hal_hmac_state_t **state_,
void *state_buffer, const size_t state_length,
const uint8_t * const key, const size_t key_length)
{
- const driver_t * const driver = check_driver(descriptor);
- internal_hmac_state_t *state = state_buffer;
- hal_hash_state_t oh;
+ const hal_hash_driver_t * const driver = check_driver(descriptor);
+ hal_hmac_state_t *state = state_buffer;
hal_error_t err;
int i;
- if (driver == NULL || opaque_state == NULL)
+ if (descriptor == NULL || driver == NULL || state_ == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
if (state_buffer != NULL && state_length < descriptor->hmac_state_length)
@@ -562,7 +559,7 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
if (state_buffer == NULL && (state = malloc(descriptor->hmac_state_length)) == NULL)
return HAL_ERROR_ALLOCATION_FAILURE;
- internal_hash_state_t *h = &state->hash_state;
+ hal_hash_state_t *h = &state->hash_state;
assert(descriptor->block_length <= sizeof(state->keybuf));
@@ -576,7 +573,8 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
return HAL_ERROR_UNSUPPORTED_KEY;
#endif
- if ((err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK)
+ if ((err = hal_hash_initialize(descriptor, &h, &state->hash_state,
+ sizeof(state->hash_state))) != HAL_OK)
goto fail;
if (state_buffer == NULL)
@@ -593,9 +591,10 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
if (key_length <= descriptor->block_length)
memcpy(state->keybuf, key, key_length);
- 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)
+ else if ((err = hal_hash_update(h, key, key_length)) != HAL_OK ||
+ (err = hal_hash_finalize(h, state->keybuf, sizeof(state->keybuf))) != HAL_OK ||
+ (err = hal_hash_initialize(descriptor, &h, &state->hash_state,
+ sizeof(state->hash_state))) != HAL_OK)
goto fail;
/*
@@ -605,7 +604,7 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
for (i = 0; i < descriptor->block_length; i++)
state->keybuf[i] ^= HMAC_IPAD;
- if ((err = hal_hash_update(oh, state->keybuf, descriptor->block_length)) != HAL_OK)
+ if ((err = hal_hash_update(h, state->keybuf, descriptor->block_length)) != HAL_OK)
goto fail;
/*
@@ -624,7 +623,7 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
* when the hash cores support such a thing.
*/
- opaque_state->state = state;
+ *state_ = state;
return HAL_OK;
@@ -638,61 +637,54 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
* Clean up HMAC state. No-op unless memory was dynamically allocated.
*/
-void hal_hmac_cleanup(hal_hmac_state_t *opaque_state)
+void hal_hmac_cleanup(hal_hmac_state_t **state_)
{
- if (opaque_state == NULL)
+ if (state_ == NULL)
return;
- internal_hmac_state_t *state = opaque_state->state;
+ hal_hmac_state_t *state = *state_;
if (state == NULL)
return;
- internal_hash_state_t *h = &state->hash_state;
+ hal_hash_state_t *h = &state->hash_state;
if ((h->flags & STATE_FLAG_STATE_ALLOCATED) == 0)
return;
memset(state, 0, h->descriptor->hmac_state_length);
free(state);
- opaque_state->state = NULL;
+ *state_ = NULL;
}
/*
* Add data to HMAC.
*/
-hal_error_t hal_hmac_update(const hal_hmac_state_t opaque_state,
+hal_error_t hal_hmac_update(hal_hmac_state_t *state,
const uint8_t * data, const size_t length)
{
- internal_hmac_state_t *state = opaque_state.state;
- internal_hash_state_t *h = &state->hash_state;
- hal_hash_state_t oh = { h };
-
if (state == NULL || data == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
- return hal_hash_update(oh, data, length);
+ return hal_hash_update(&state->hash_state, data, length);
}
/*
* Finish and return HMAC.
*/
-hal_error_t hal_hmac_finalize(const hal_hmac_state_t opaque_state,
+hal_error_t hal_hmac_finalize(hal_hmac_state_t *state,
uint8_t *hmac, const size_t length)
{
- internal_hmac_state_t *state = opaque_state.state;
- internal_hash_state_t *h = &state->hash_state;
- const hal_hash_descriptor_t *descriptor;
- hal_hash_state_t oh = { h };
- uint8_t d[HAL_MAX_HASH_DIGEST_LENGTH];
- hal_error_t err;
-
if (state == NULL || hmac == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
- descriptor = h->descriptor;
+ hal_hash_state_t *h = &state->hash_state;
+ const hal_hash_descriptor_t *descriptor = h->descriptor;
+ uint8_t d[HAL_MAX_HASH_DIGEST_LENGTH];
+ hal_error_t err;
+
assert(descriptor != NULL && descriptor->digest_length <= sizeof(d));
/*
@@ -700,11 +692,12 @@ hal_error_t hal_hmac_finalize(const hal_hmac_state_t opaque_state,
* to get HMAC. Key was prepared for this in hal_hmac_initialize().
*/
- if ((err = hal_hash_finalize(oh, d, sizeof(d))) != HAL_OK ||
- (err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK ||
- (err = hal_hash_update(oh, state->keybuf, descriptor->block_length)) != HAL_OK ||
- (err = hal_hash_update(oh, d, descriptor->digest_length)) != HAL_OK ||
- (err = hal_hash_finalize(oh, hmac, length)) != HAL_OK)
+ if ((err = hal_hash_finalize(h, d, sizeof(d))) != HAL_OK ||
+ (err = hal_hash_initialize(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 ||
+ (err = hal_hash_finalize(h, hmac, length)) != HAL_OK)
return err;
return HAL_OK;