aboutsummaryrefslogtreecommitdiffstats
path: root/extra
diff options
context:
space:
mode:
Diffstat (limited to 'extra')
-rw-r--r--extra/libkeccak_state_copy.c25
-rw-r--r--extra/libkeccak_state_create.c20
-rw-r--r--extra/libkeccak_state_duplicate.c20
-rw-r--r--extra/libkeccak_state_fast_free.c5
-rw-r--r--extra/libkeccak_state_free.c5
-rw-r--r--extra/libkeccak_state_marshal.c55
-rw-r--r--extra/libkeccak_state_reset.c5
-rw-r--r--extra/libkeccak_state_unmarshal.c66
-rw-r--r--extra/libkeccak_state_wipe.c15
-rw-r--r--extra/libkeccak_state_wipe_message.c18
-rw-r--r--extra/libkeccak_state_wipe_sponge.c18
11 files changed, 252 insertions, 0 deletions
diff --git a/extra/libkeccak_state_copy.c b/extra/libkeccak_state_copy.c
new file mode 100644
index 0000000..950fc91
--- /dev/null
+++ b/extra/libkeccak_state_copy.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+/**
+ * Make a copy of a 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_state_copy(struct libkeccak_state *restrict dest, const struct libkeccak_state *restrict src)
+{
+ *dest = *src;
+ if (src->mlen) {
+ dest->M = malloc(src->mlen * sizeof(char));
+ if (!dest->M)
+ return -1;
+ memcpy(dest->M, src->M, src->mptr * sizeof(char));
+ } else {
+ dest->M = NULL;
+ }
+ return 0;
+}
diff --git a/extra/libkeccak_state_create.c b/extra/libkeccak_state_create.c
new file mode 100644
index 0000000..eda9011
--- /dev/null
+++ b/extra/libkeccak_state_create.c
@@ -0,0 +1,20 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+/**
+ * Wrapper for `libkeccak_state_initialise` that also allocates the states
+ *
+ * @param spec The specifications for the state
+ * @return The state, `NULL` on error
+ */
+struct libkeccak_state *
+libkeccak_state_create(const struct libkeccak_spec *spec)
+{
+ struct libkeccak_state *state = malloc(sizeof(struct libkeccak_state));
+ if (!state || libkeccak_state_initialise(state, spec)) {
+ free(state);
+ return NULL;
+ }
+ return state;
+}
diff --git a/extra/libkeccak_state_duplicate.c b/extra/libkeccak_state_duplicate.c
new file mode 100644
index 0000000..3d90d02
--- /dev/null
+++ b/extra/libkeccak_state_duplicate.c
@@ -0,0 +1,20 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+/**
+ * A wrapper for `libkeccak_state_copy` that also allocates the duplicate
+ *
+ * @param src The state to duplicate
+ * @return The duplicate, `NULL` on error
+ */
+struct libkeccak_state *
+libkeccak_state_duplicate(const struct libkeccak_state *src)
+{
+ struct libkeccak_state *dest = malloc(sizeof(struct libkeccak_state));
+ if (!dest || libkeccak_state_copy(dest, src)) {
+ libkeccak_state_free(dest);
+ return NULL;
+ }
+ return dest;
+}
diff --git a/extra/libkeccak_state_fast_free.c b/extra/libkeccak_state_fast_free.c
new file mode 100644
index 0000000..af75e39
--- /dev/null
+++ b/extra/libkeccak_state_fast_free.c
@@ -0,0 +1,5 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+extern inline void libkeccak_state_fast_free(struct libkeccak_state *);
diff --git a/extra/libkeccak_state_free.c b/extra/libkeccak_state_free.c
new file mode 100644
index 0000000..6a879b3
--- /dev/null
+++ b/extra/libkeccak_state_free.c
@@ -0,0 +1,5 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+extern inline void libkeccak_state_free(volatile struct libkeccak_state *);
diff --git a/extra/libkeccak_state_marshal.c b/extra/libkeccak_state_marshal.c
new file mode 100644
index 0000000..7541164
--- /dev/null
+++ b/extra/libkeccak_state_marshal.c
@@ -0,0 +1,55 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wcast-align"
+#endif
+
+
+/**
+ * Marshal a `struct libkeccak_state` into a buffer
+ *
+ * @param state The state to marshal
+ * @param data_ The output buffer, can be `NULL`
+ * @return The number of bytes stored to `data`
+ */
+size_t
+libkeccak_state_marshal(const struct libkeccak_state *restrict state, void *restrict data_)
+{
+#define set(VAR)\
+ do {\
+ __builtin_memcpy(data, &state->VAR, sizeof(state->VAR));\
+ data += sizeof(state->VAR);\
+ } while (0)
+
+ unsigned char *restrict start = data_;
+ unsigned char *restrict data = start;
+
+ if (!data) {
+ return 7 * sizeof(long int) +
+ 1 * sizeof(int64_t) +
+ sizeof(state->S) +
+ 2 * sizeof(size_t) +
+ state->mptr;
+ }
+
+ set(r);
+ set(c);
+ set(n);
+ set(b);
+ set(w);
+ set(wmod);
+ set(l);
+ set(nr);
+ __builtin_memcpy(data, state->S, sizeof(state->S));
+ data += sizeof(state->S);
+ set(mptr);
+ set(mlen);
+ memcpy(data, state->M, state->mptr * sizeof(char));
+ data += state->mptr;
+
+ return (size_t)(data - start);
+
+#undef set
+}
diff --git a/extra/libkeccak_state_reset.c b/extra/libkeccak_state_reset.c
new file mode 100644
index 0000000..44eb5a4
--- /dev/null
+++ b/extra/libkeccak_state_reset.c
@@ -0,0 +1,5 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+extern inline void libkeccak_state_reset(struct libkeccak_state *);
diff --git a/extra/libkeccak_state_unmarshal.c b/extra/libkeccak_state_unmarshal.c
new file mode 100644
index 0000000..4714566
--- /dev/null
+++ b/extra/libkeccak_state_unmarshal.c
@@ -0,0 +1,66 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wcast-align"
+#endif
+
+
+/**
+ * Unmarshal a `struct libkeccak_state` from a buffer
+ *
+ * @param state The slot for the unmarshalled state, must not be
+ * initialised (memory leak otherwise), can be `NULL`
+ * @param data_ The input buffer
+ * @return The number of bytes read from `data`, 0 on error
+ */
+size_t
+libkeccak_state_unmarshal(struct libkeccak_state *restrict state, const void *restrict data_)
+{
+#define get(VAR) \
+ do {\
+ __builtin_memcpy(&state->VAR, data, sizeof(state->VAR));\
+ data += sizeof(state->VAR);\
+ } while (0)
+
+ const unsigned char *restrict start = data_;
+ const unsigned char *restrict data = start;
+ size_t mptr;
+
+ if (!state) {
+ data += 7U * sizeof(long int);
+ data += 1U * sizeof(int64_t);
+ data += sizeof(state->S);
+ mptr = *(const size_t *)data;
+ data += 2U * sizeof(size_t);
+ data += mptr;
+ return (size_t)(data - start);
+ }
+
+ get(r);
+ get(c);
+ get(n);
+ get(b);
+ get(w);
+ get(wmod);
+ get(l);
+ get(nr);
+ memcpy(state->S, data, sizeof(state->S));
+ data += sizeof(state->S);
+ get(mptr);
+ get(mlen);
+ if (state->mptr) {
+ state->M = malloc(state->mptr * sizeof(char));
+ if (!state->M)
+ return 0;
+ memcpy(state->M, data, state->mptr * sizeof(char));
+ data += state->mptr;
+ } else {
+ state->M = NULL;
+ }
+
+ return (size_t)(data - start);
+
+#undef get
+}
diff --git a/extra/libkeccak_state_wipe.c b/extra/libkeccak_state_wipe.c
new file mode 100644
index 0000000..728f72f
--- /dev/null
+++ b/extra/libkeccak_state_wipe.c
@@ -0,0 +1,15 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+/**
+ * Wipe sensitive data without freeing any data
+ *
+ * @param state The state that should be wipe
+ */
+void
+libkeccak_state_wipe(volatile struct libkeccak_state *state)
+{
+ libkeccak_state_wipe_message(state);
+ libkeccak_state_wipe_sponge(state);
+}
diff --git a/extra/libkeccak_state_wipe_message.c b/extra/libkeccak_state_wipe_message.c
new file mode 100644
index 0000000..364eb8e
--- /dev/null
+++ b/extra/libkeccak_state_wipe_message.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+/**
+ * Wipe data in the state's message without freeing any data
+ *
+ * @param state The state that should be wipe
+ */
+void
+libkeccak_state_wipe_message(volatile struct libkeccak_state *state)
+{
+ volatile unsigned char *restrict M = state->M;
+ size_t i;
+
+ for (i = 0; i < state->mptr; i++)
+ M[i] = 0;
+}
diff --git a/extra/libkeccak_state_wipe_sponge.c b/extra/libkeccak_state_wipe_sponge.c
new file mode 100644
index 0000000..91e845a
--- /dev/null
+++ b/extra/libkeccak_state_wipe_sponge.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "../common.h"
+
+
+/**
+ * Wipe data in the state's sponge without freeing any data
+ *
+ * @param state The state that should be wipe
+ */
+void
+libkeccak_state_wipe_sponge(volatile struct libkeccak_state *state)
+{
+ volatile int64_t *restrict S = state->S;
+ size_t i;
+
+ for (i = 0; i < 25; i++)
+ S[i] = 0;
+}