From 8b24277c444fdafa244c87d0ca5e3a7c47eaf76d Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Sat, 25 Jul 2015 17:08:25 +0200
Subject: beginning of hmac implementation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Mattias Andrée <maandree@operamail.com>
---
 src/libkeccak.h          |   1 +
 src/libkeccak/mac/hmac.c | 273 +++++++++++++++++++++++++++++++++++
 src/libkeccak/mac/hmac.h | 366 +++++++++++++++++++++++++++++++++++++++++++++++
 src/libkeccak/state.h    |  17 ++-
 4 files changed, 648 insertions(+), 9 deletions(-)
 create mode 100644 src/libkeccak/mac/hmac.c
 create mode 100644 src/libkeccak/mac/hmac.h

(limited to 'src')

diff --git a/src/libkeccak.h b/src/libkeccak.h
index 3812a6b..cedbc94 100644
--- a/src/libkeccak.h
+++ b/src/libkeccak.h
@@ -26,6 +26,7 @@
 #include "libkeccak/digest.h"
 #include "libkeccak/hex.h"
 #include "libkeccak/files.h"
+#include "libkeccak/mac/hmac.h"
 
 
 #endif
diff --git a/src/libkeccak/mac/hmac.c b/src/libkeccak/mac/hmac.c
new file mode 100644
index 0000000..b679e8e
--- /dev/null
+++ b/src/libkeccak/mac/hmac.c
@@ -0,0 +1,273 @@
+/**
+ * libkeccak – Keccak-family hashing library
+ * 
+ * Copyright © 2014, 2015  Mattias Andrée (maandree@member.fsf.org)
+ * 
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "hmac.h"
+
+#include "../digest.h"
+
+
+
+/**
+ * The outer pad pattern
+ */
+#define OUTER_PAD  0x5C
+
+/**
+ * The inner pad pattern
+ */
+#define INNER_PAD  0x36
+
+
+
+/**
+ * Change to HMAC-hashing key on the state
+ * 
+ * @param   state       The state that should be reset
+ * @param   key         The new key
+ * @param   key_length  The length of key, in bits
+ * @return              Zero on success, -1 on error
+ */
+int libkeccak_hmac_set_key(libkeccak_hmac_state_t* restrict state, const char* restrict key, size_t key_length)
+{
+  size_t i, size, new_key_length, key_bytes;
+  char* old;
+  
+  size = (size_t)(state->sponge.r) > key_length ? (size_t)(state->sponge.r) : key_length;
+  new_key_length = size;
+  size = (size + 7) >> 3;
+  key_bytes = (key_length + 7) >> 3;
+  
+  if (size != key_bytes)
+    {
+      state->key_opad = realloc(old = state->key_opad, 2 * size);
+      if (state->key_opad == NULL)
+	return state->key_opad = old, -1;
+      state->key_ipad = state->key_opad + size / sizeof(char);
+    }
+  
+  memcpy(state->key_opad, key, key_bytes);
+  if (key_length & 7)
+    state->key_opad[(key_bytes >> 3) - 1] &= (1 << (key_length & 7)) - 1;
+  
+  if ((size_t)(state->sponge.r) > key_length)
+    __builtin_memset(state->key_opad + key_bytes / sizeof(char), 0, size - key_bytes);
+  
+  for (i = 0; i < size; i++)
+    state->key_ipad[i] = state->key_opad[i] ^ INNER_PAD,
+    state->key_opad[i] ^= OUTER_PAD;
+  
+  state->key_length = new_key_length;
+  
+  return 0;
+}
+
+
+/**
+ * Wipe sensitive data wihout freeing any data
+ * 
+ * @param  state  The state that should be wipe
+ */
+void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t* restrict state)
+{
+  volatile char* restrict key_pads;
+  size_t i, size;
+  key_pads = state->key_opad;
+  size = 2 * ((state->key_length + 7) >> 3);
+  libkeccak_state_wipe(&(state->sponge));
+  for (i = 0; i < size; i++)
+    key_pads[i] = 0;
+  state->leftover = 0;
+  __builtin_memset(state->buffer, 0, state->buffer_size);
+}
+
+
+/**
+ * Make a copy of an HMAC hashing-state
+ * 
+ * @param   dest  The slot for the duplicate, must not be initialised (memory leak otherwise)
+ * @param   src   The state to duplicate
+ * @return        Zero on success, -1 on error
+ */
+int libkeccak_hmac_copy(libkeccak_hmac_state_t* restrict dest, const libkeccak_hmac_state_t* restrict src)
+{
+  int saved_errno;
+  size_t size;
+  
+  dest->key_opad = NULL;
+  dest->key_ipad = NULL;
+  
+  if (libkeccak_state_copy(&(dest->sponge), &(src->sponge)) < 0)
+    return -1;
+  
+  dest->key_length = src->key_length;
+  dest->leftover = src->leftover;
+  
+  size = (src->key_length + 7) >> 3;
+  dest->key_opad = malloc(2 * size);
+  if (dest->key_opad == NULL)
+    return saved_errno = errno, libkeccak_state_destroy(&(dest->sponge)), errno = saved_errno, -1;
+  dest->key_ipad = dest->key_opad + size / sizeof(char);
+  
+  memcpy(dest->key_opad, src->key_opad, size);
+  memcpy(dest->key_ipad, src->key_ipad, size);
+  
+  return 0;
+}
+
+
+/**
+ * Unmarshal a `libkeccak_hmac_state_t` from a buffer
+ * 
+ * @param   state  The slot for the unmarshalled state, must not be initialised (memory leak otherwise)
+ * @param   data   The input buffer
+ * @return         The number of bytes read from `data`, 0 on error
+ */
+size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t* restrict state, const char* restrict data)
+{
+  size_t parsed, size, i;
+  int saved_errno;
+  
+  state->key_opad = NULL;
+  state->key_ipad = NULL;
+  
+  parsed = libkeccak_state_unmarshal(&(state->sponge), data);
+  if (parsed == 0)
+    return 0;
+  
+  data += parsed / sizeof(char);
+  state->key_length = *(const size_t*)data;
+  data += sizeof(size_t) / sizeof(char);
+  size = (state->key_length + 7) >> 3;
+  
+  state->key_opad = malloc(2 * size);
+  if (state->key_opad == NULL)
+    return saved_errno = errno, libkeccak_state_destroy(&(state->sponge)), errno = saved_errno, -1;
+  memcpy(state->key_opad, data, size);
+  data += size / sizeof(char);
+  
+  if (data[0])
+    {
+      state->key_ipad = state->key_opad + size / sizeof(char);
+      memcpy(state->key_ipad, state->key_opad, size);
+      for (i = 0; i < size / sizeof(char); i++)
+	state->key_ipad[i] ^= (char)(OUTER_PAD ^ INNER_PAD);
+    }
+  
+  state->leftover = data[1];
+  state->buffer = NULL;
+  state->buffer_size = 0;
+  
+  return parsed + sizeof(size_t) + size + 2 * sizeof(char);
+}
+
+
+/**
+ * Absorb more, or the first part, of the message
+ * without wiping sensitive data when possible
+ * 
+ * @param   state   The hashing state
+ * @param   msg     The partial message
+ * @param   msglen  The length of the partial message, in bytes
+ * @return          Zero on success, -1 on error
+ */
+__attribute__((nonnull))
+int libkeccak_hmac_fast_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen)
+{
+  char* old;
+  size_t i;
+  int n, cn;
+  
+  if (state->key_ipad != NULL)
+    {
+      if (libkeccak_fast_update(&(state->sponge), state->key_ipad, state->key_length >> 3) < 0)
+	return -1;
+      if (state->key_length & 7)
+	state->leftover = state->key_ipad[(state->key_length >> 3)];
+      state->key_ipad = NULL;
+    }
+  
+  if (!(state->key_length & 7))
+    return libkeccak_fast_update(&(state->sponge), msg, msglen);
+  
+  if (msglen != state->buffer_size)
+    {
+      state->buffer = realloc(old = state->buffer, state->buffer_size = msglen);
+      if (state->buffer == NULL)
+	return state->buffer = old, -1;
+    }
+  
+  n = (int)(state->key_length & 7);
+  cn = 8 - n;
+  for (i = 1; i < msglen; i++)
+    state->buffer[i] = (((unsigned char)(msg[i - 1])) >> cn) | (msg[i] << n);
+  state->buffer[0] = (state->leftover & ((1 << n) - 1)) | (msg[0] << n);
+  state->leftover = ((unsigned char)(msg[msglen - 1])) >> cn;
+  
+  return libkeccak_fast_update(&(state->sponge), state->buffer, msglen);
+}
+
+
+/**
+ * Absorb more, or the first part, of the message
+ * and wipe sensitive data when possible
+ * 
+ * @param   state   The hashing state
+ * @param   msg     The partial message
+ * @param   msglen  The length of the partial message, in bytes
+ * @return          Zero on success, -1 on error
+ */
+__attribute__((nonnull))
+int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen)
+{
+  size_t i;
+  int n, cn, r, saved_errno;
+  
+  if (state->key_ipad != NULL)
+    {
+      if (libkeccak_update(&(state->sponge), state->key_ipad, state->key_length >> 3) < 0)
+	return -1;
+      if (state->key_length & 7)
+	state->leftover = state->key_ipad[(state->key_length >> 3)];
+      state->key_ipad = NULL;
+    }
+  
+  if (!(state->key_length & 7))
+    return libkeccak_update(&(state->sponge), msg, msglen);
+  
+  if (msglen != state->buffer_size)
+    {
+      free(state->buffer);
+      state->buffer = malloc(state->buffer_size = msglen);
+      if (state->buffer == NULL)
+	return -1;
+    }
+  
+  n = (int)(state->key_length & 7);
+  cn = 8 - n;
+  for (i = 1; i < msglen; i++)
+    state->buffer[i] = (((unsigned char)(msg[i - 1])) >> cn) | (msg[i] << n);
+  state->buffer[0] = (state->leftover & ((1 << n) - 1)) | (msg[0] << n);
+  state->leftover = ((unsigned char)(msg[msglen - 1])) >> cn;
+  
+  r = libkeccak_update(&(state->sponge), state->buffer, msglen);
+  saved_errno = errno;
+  __builtin_memset(state->buffer, 0, msglen);
+  errno = saved_errno;
+  return r;
+}
+
diff --git a/src/libkeccak/mac/hmac.h b/src/libkeccak/mac/hmac.h
new file mode 100644
index 0000000..9526ef8
--- /dev/null
+++ b/src/libkeccak/mac/hmac.h
@@ -0,0 +1,366 @@
+/**
+ * libkeccak – Keccak-family hashing library
+ * 
+ * Copyright © 2014, 2015  Mattias Andrée (maandree@member.fsf.org)
+ * 
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef LIBKECCAK_MAC_HMAC_H
+#define LIBKECCAK_MAC_HMAC_H  1
+
+
+/* The Keccak hash-function, that was selected by NIST as the SHA-3 competition winner,
+ * doesn't need this nested approach and can be used to generate a MAC by simply prepending
+ * the key to the message. [http://keccak.noekeon.org]
+ */
+
+
+#include "../spec.h"
+#include "../state.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+
+
+/**
+ * Datastructure that describes the state of an HMAC-hashing process
+ */
+typedef struct libkeccak_hmac_state
+{
+  /**
+   * The key right-padded and XOR:ed with the outer pad
+   */
+  char* restrict key_opad;
+  
+  /**
+   * The key right-padded and XOR:ed with the inner pad
+   */
+  char* restrict key_ipad;
+  /* Not marshalled, implicitly unmarshalled using `key_opad`. */
+  /* Shares allocation with `key_opad`, do not `free`. */
+  
+  /**
+   * The length of key, but at least the input block size, in bits
+   */
+  size_t key_length;
+  
+  /**
+   * The state of the underlaying hash-algorithm
+   */
+  libkeccak_state_t sponge;
+  
+  /**
+   * Buffer used to temporarily store bit shift message if
+   * `key_length` is not zero modulus 8
+   */
+  char* restrict buffer;
+  
+  /**
+   * The allocation size of `buffer`
+   */
+  size_t buffer_size;
+  
+  /**
+   * Part of feed key, message or digest that have not been passed yet
+   */
+  char leftover;
+  
+  char __pad[sizeof(void*) / sizeof(char) - 1];
+  
+} libkeccak_hmac_state_t;
+
+
+
+/**
+ * Change to HMAC-hashing key on the state
+ * 
+ * @param   state       The state that should be reset
+ * @param   key         The new key
+ * @param   key_length  The length of key, in bits
+ * @return              Zero on success, -1 on error
+ */
+__attribute__((nonnull(1), unused))
+int libkeccak_hmac_set_key(libkeccak_hmac_state_t* restrict state, const char* restrict key, size_t key_length);
+
+
+/**
+ * Initialise an HMAC hashing-state according to hashing specifications
+ * 
+ * @param   state       The state that should be initialised
+ * @param   spec        The specifications for the state
+ * @param   key         The key
+ * @param   key_length  The length of key, in bits
+ * @return              Zero on success, -1 on error
+ */
+static inline __attribute__((nonnull))
+int libkeccak_hmac_initialise(libkeccak_hmac_state_t* restrict state, const libkeccak_spec_t* restrict spec,
+			      const char* restrict key, size_t key_length)
+{
+  int saved_errno;
+  if (libkeccak_state_initialise(&(state->sponge), spec) < 0)
+    return -1;
+  if (libkeccak_hmac_set_key(state, key, key_length) < 0)
+    return saved_errno = errno, libkeccak_state_destroy(&(state->sponge)), errno = saved_errno, -1;
+  state->leftover = 0;
+  state->buffer = NULL;
+  state->buffer_size = 0;
+  return 0;
+}
+
+
+/**
+ * Wrapper for `libkeccak_hmac_initialise` that also allocates the states
+ * 
+ * @param   spec        The specifications for the state
+ * @param   key         The key
+ * @param   key_length  The length of key, in bits
+ * @return              The state, `NULL` on error
+ */
+static inline __attribute__((nonnull, unused, warn_unused_result))
+libkeccak_hmac_state_t* libkeccak_hmac_create(const libkeccak_spec_t* restrict spec,
+					      const char* restrict key, size_t key_length)
+{
+  libkeccak_hmac_state_t* restrict state = malloc(sizeof(libkeccak_hmac_state_t));
+  int saved_errno;
+  if ((state == NULL) || libkeccak_hmac_initialise(state, spec, key, key_length))
+    return saved_errno = errno, free(state), errno = saved_errno, NULL;
+  return state;
+}
+
+
+/**
+ * Reset an HMAC-hashing state according to hashing specifications,
+ * you can choose whether to change the key
+ * 
+ * @param   state       The state that should be reset
+ * @param   key         The new key, `NULL` to keep the old key
+ * @param   key_length  The length of key, in bits, ignored if `key == NULL`
+ * @return              Zero on success, -1 on error
+ */
+static inline __attribute__((nonnull(1), unused))
+int libkeccak_hmac_reset(libkeccak_hmac_state_t* restrict state, const char* restrict key, size_t key_length)
+{
+  libkeccak_state_reset(&(state->sponge));
+  return key != NULL ? libkeccak_hmac_set_key(state, key, key_length) : 0;
+}
+
+
+/**
+ * Wipe sensitive data wihout freeing any data
+ * 
+ * @param  state  The state that should be wipe
+ */
+__attribute__((nonnull, nothrow, optimize("-O0")))
+void libkeccak_hmac_wipe(volatile libkeccak_hmac_state_t* restrict state);
+
+
+/**
+ * Release resources allocation for an HMAC hashing-state without wiping sensitive data
+ * 
+ * @param  state  The state that should be destroyed
+ */
+static inline
+void libkeccak_hmac_fast_destroy(libkeccak_hmac_state_t* restrict state)
+{
+  if (state == NULL)
+    return;
+  free(state->key_opad);
+  state->key_opad = NULL;
+  state->key_ipad = NULL;
+  state->key_length = 0;
+  free(state->buffer);
+  state->buffer = NULL;
+  state->buffer_size = 0;
+}
+
+
+/**
+ * Release resources allocation for an HMAC hasing-state and wipe sensitive data
+ * 
+ * @param  state  The state that should be destroyed
+ */
+static inline __attribute__((unused, optimize("-O0")))
+void libkeccak_hmac_destroy(volatile libkeccak_hmac_state_t* restrict state)
+{
+  if (state == NULL)
+    return;
+  libkeccak_hmac_wipe(state);
+  free(state->key_opad);
+  state->key_opad = NULL;
+  state->key_ipad = NULL;
+  state->key_length = 0;
+  state->leftover = 0;
+  free(state->buffer);
+  state->buffer = NULL;
+  state->buffer_size = 0;
+}
+
+
+/**
+ * Wrapper for `libkeccak_fast_destroy` that also frees the allocation of the state
+ * 
+ * @param  state  The state that should be freed
+ */
+static inline __attribute__((unused))
+void libkeccak_hmac_fast_free(libkeccak_hmac_state_t* restrict state)
+{
+  libkeccak_hmac_fast_destroy(state);
+  free(state);
+}
+
+
+/**
+ * Wrapper for `libkeccak_hmac_destroy` that also frees the allocation of the state
+ * 
+ * @param  state  The state that should be freed
+ */
+static inline __attribute__((unused, optimize("-O0")))
+void libkeccak_hmac_free(volatile libkeccak_hmac_state_t* restrict state)
+{
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wcast-qual"
+  libkeccak_hmac_destroy(state);
+  free((libkeccak_hmac_state_t*)state);
+# pragma GCC diagnostic pop
+}
+
+
+/**
+ * Make a copy of an HMAC hashing-state
+ * 
+ * @param   dest  The slot for the duplicate, must not be initialised (memory leak otherwise)
+ * @param   src   The state to duplicate
+ * @return        Zero on success, -1 on error
+ */
+__attribute__((nonnull))
+int libkeccak_hmac_copy(libkeccak_hmac_state_t* restrict dest, const libkeccak_hmac_state_t* restrict src);
+
+
+/**
+ * A wrapper for `libkeccak_hmac_copy` that also allocates the duplicate
+ * 
+ * @param   src  The state to duplicate
+ * @return       The duplicate, `NULL` on error
+ */
+static inline __attribute__((nonnull, unused, warn_unused_result))
+libkeccak_hmac_state_t* libkeccak_hmac_duplicate(const libkeccak_hmac_state_t* restrict src)
+{
+  libkeccak_hmac_state_t* restrict dest = malloc(sizeof(libkeccak_hmac_state_t));
+  int saved_errno;
+  if ((dest == NULL) || libkeccak_hmac_copy(dest, src))
+    return saved_errno = errno, libkeccak_hmac_free(dest), errno = saved_errno, NULL;
+  return dest;
+}
+
+
+/**
+ * Calculates the allocation size required for the second argument
+ * of `libkeccak_hmac_marshal` (`char* restrict data)`)
+ * 
+ * @param   state  The state as it will be marshalled by a subsequent call to `libkeccak_hamc_marshal`
+ * @return         The allocation size needed for the buffer to which the state will be marshalled
+ */
+static inline __attribute__((nonnull, nothrow, unused, warn_unused_result, pure))
+size_t libkeccak_hmac_marshal_size(const libkeccak_hmac_state_t* restrict state)
+{
+  return libkeccak_state_marshal_size(&(state->sponge)) + sizeof(size_t) +
+         ((state->key_length + 7) >> 3) + 2 * sizeof(char);
+}
+
+
+/**
+ * Marshal a `libkeccak_hmac_state_t` into a buffer
+ * 
+ * @param   state  The state to marshal
+ * @param   data   The output buffer
+ * @return         The number of bytes stored to `data`
+ */
+static inline __attribute__((nonnull, nothrow))
+size_t libkeccak_hmac_marshal(const libkeccak_hmac_state_t* restrict state, char* restrict data)
+{
+  size_t written = libkeccak_state_marshal(&(state->sponge), data);
+  data += written / sizeof(char);
+  *(size_t*)data = state->key_length;
+  data += sizeof(size_t) / sizeof(char);
+  memcpy(data, state->key_opad, (state->key_length + 7) >> 3);
+  data += ((state->key_length + 7) >> 3) / sizeof(char);
+  data[0] = (char)(state->key_ipad != NULL);
+  data[1] = state->leftover;
+  return written + sizeof(size_t) + ((state->key_length + 7) >> 3) + 2 * sizeof(char);
+}
+
+
+/**
+ * Unmarshal a `libkeccak_hmac_state_t` from a buffer
+ * 
+ * @param   state  The slot for the unmarshalled state, must not be initialised (memory leak otherwise)
+ * @param   data   The input buffer
+ * @return         The number of bytes read from `data`, 0 on error
+ */
+__attribute__((nonnull))
+size_t libkeccak_hmac_unmarshal(libkeccak_hmac_state_t* restrict state, const char* restrict data);
+
+
+/**
+ * Gets the number of bytes the `libkeccak_hmac_state_t` stored
+ * at the beginning of `data` occupies
+ * 
+ * @param   data  The data buffer
+ * @return        The byte size of the stored state
+ */
+static inline __attribute__((nonnull, nothrow, warn_unused_result, pure))
+size_t libkeccak_hmac_unmarshal_skip(const char* restrict data)
+{
+  size_t skip = libkeccak_state_unmarshal_skip(data);
+  data += skip / sizeof(char);
+  return skip + sizeof(size_t) + *(const size_t*)data + 2 * sizeof(char);
+}
+
+
+/**
+ * Absorb more, or the first part, of the message
+ * without wiping sensitive data when possible
+ * 
+ * @param   state   The hashing state
+ * @param   msg     The partial message
+ * @param   msglen  The length of the partial message, in bytes
+ * @return          Zero on success, -1 on error
+ */
+__attribute__((nonnull))
+int libkeccak_hmac_fast_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen);
+
+
+/**
+ * Absorb more, or the first part, of the message
+ * and wipe sensitive data when possible
+ * 
+ * @param   state   The hashing state
+ * @param   msg     The partial message
+ * @param   msglen  The length of the partial message, in bytes
+ * @return          Zero on success, -1 on error
+ */
+__attribute__((nonnull))
+int libkeccak_hmac_update(libkeccak_hmac_state_t* restrict state, const char* restrict msg, size_t msglen);
+
+
+/* TODO libkeccak_hmac_fast_digest(); */
+/* TODO libkeccak_hmac_digest(); */
+
+
+#endif
+
diff --git a/src/libkeccak/state.h b/src/libkeccak/state.h
index 33785a4..69a2455 100644
--- a/src/libkeccak/state.h
+++ b/src/libkeccak/state.h
@@ -30,7 +30,7 @@
 
 
 /**
- * Satastructure that describes the state of a hashing process
+ * Datastructure that describes the state of a hashing process
  * 
  * The `char`-size of the output hashsum is calculated by `(.n + 7) / 8`
  */
@@ -114,11 +114,10 @@ int libkeccak_state_initialise(libkeccak_state_t* restrict state, const libkecca
 /**
  * Reset a state according to hashing specifications
  * 
- * @param   state  The state that should be reset
- * @return         Zero on success, -1 on error
+ * @param  state  The state that should be reset
  */
-__attribute__((nonnull, nothrow, unused))
-static inline void libkeccak_state_reset(libkeccak_state_t* restrict state)
+static inline __attribute__((nonnull, nothrow, unused))
+void libkeccak_state_reset(libkeccak_state_t* restrict state)
 {
   state->mptr = 0;
   __builtin_memset(state->S, 0, sizeof(state->S));
@@ -184,8 +183,8 @@ void libkeccak_state_destroy(volatile libkeccak_state_t* restrict state)
 /**
  * Wrapper for `libkeccak_state_initialise` that also allocates the states
  * 
- * @param   spec   The specifications for the state
- * @return         The state, `NULL` on error
+ * @param   spec  The specifications for the state
+ * @return        The state, `NULL` on error
  */
 static inline __attribute__((nonnull, unused, warn_unused_result))
 libkeccak_state_t* libkeccak_state_create(const libkeccak_spec_t* restrict spec)
@@ -241,8 +240,8 @@ int libkeccak_state_copy(libkeccak_state_t* restrict dest, const libkeccak_state
 /**
  * A wrapper for `libkeccak_state_copy` that also allocates the duplicate
  * 
- * @param   src   The state to duplicate
- * @return        The duplicate, `NULL` on error
+ * @param   src  The state to duplicate
+ * @return       The duplicate, `NULL` on error
  */
 static inline __attribute__((nonnull, unused, warn_unused_result))
 libkeccak_state_t* libkeccak_state_duplicate(const libkeccak_state_t* restrict src)
-- 
cgit v1.2.3-70-g09d2