summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/sha3
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2016-10-20 16:18:38 +0200
committerYves-Alexis Perez <corsac@debian.org>2016-10-20 16:18:38 +0200
commit25663e04c3ab01ef8dc9f906608282319cfea2db (patch)
treea0ca5e70f66d74dbe552c996a4f3a285cdfc35e4 /src/libstrongswan/plugins/sha3
parentbf372706c469764d59e9f29c39e3ecbebd72b8d2 (diff)
downloadvyos-strongswan-25663e04c3ab01ef8dc9f906608282319cfea2db.tar.gz
vyos-strongswan-25663e04c3ab01ef8dc9f906608282319cfea2db.zip
New upstream version 5.5.1
Diffstat (limited to 'src/libstrongswan/plugins/sha3')
-rw-r--r--src/libstrongswan/plugins/sha3/Makefile.am5
-rw-r--r--src/libstrongswan/plugins/sha3/Makefile.in15
-rw-r--r--src/libstrongswan/plugins/sha3/sha3_hasher.c447
-rw-r--r--src/libstrongswan/plugins/sha3/sha3_keccak.c498
-rw-r--r--src/libstrongswan/plugins/sha3/sha3_keccak.h82
-rw-r--r--src/libstrongswan/plugins/sha3/sha3_plugin.c6
-rw-r--r--src/libstrongswan/plugins/sha3/sha3_shake.c143
-rw-r--r--src/libstrongswan/plugins/sha3/sha3_shake.h48
8 files changed, 825 insertions, 419 deletions
diff --git a/src/libstrongswan/plugins/sha3/Makefile.am b/src/libstrongswan/plugins/sha3/Makefile.am
index 7ccf58ce6..a776b1de0 100644
--- a/src/libstrongswan/plugins/sha3/Makefile.am
+++ b/src/libstrongswan/plugins/sha3/Makefile.am
@@ -11,6 +11,9 @@ plugin_LTLIBRARIES = libstrongswan-sha3.la
endif
libstrongswan_sha3_la_SOURCES = \
- sha3_plugin.h sha3_plugin.c sha3_hasher.c sha3_hasher.h
+ sha3_plugin.h sha3_plugin.c \
+ sha3_hasher.c sha3_hasher.h \
+ sha3_shake.h sha3_shake.c \
+ sha3_keccak.h sha3_keccak.c
libstrongswan_sha3_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/sha3/Makefile.in b/src/libstrongswan/plugins/sha3/Makefile.in
index 0d29fcb4b..9e237a933 100644
--- a/src/libstrongswan/plugins/sha3/Makefile.in
+++ b/src/libstrongswan/plugins/sha3/Makefile.in
@@ -137,7 +137,8 @@ am__uninstall_files_from_dir = { \
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
libstrongswan_sha3_la_LIBADD =
-am_libstrongswan_sha3_la_OBJECTS = sha3_plugin.lo sha3_hasher.lo
+am_libstrongswan_sha3_la_OBJECTS = sha3_plugin.lo sha3_hasher.lo \
+ sha3_shake.lo sha3_keccak.lo
libstrongswan_sha3_la_OBJECTS = $(am_libstrongswan_sha3_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -350,7 +351,6 @@ clearsilver_LIBS = @clearsilver_LIBS@
cmd_plugins = @cmd_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
-dbusservicedir = @dbusservicedir@
dev_headers = @dev_headers@
docdir = @docdir@
dvidir = @dvidir@
@@ -384,8 +384,6 @@ libiptc_LIBS = @libiptc_LIBS@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
-maemo_CFLAGS = @maemo_CFLAGS@
-maemo_LIBS = @maemo_LIBS@
manager_plugins = @manager_plugins@
mandir = @mandir@
medsrv_plugins = @medsrv_plugins@
@@ -439,6 +437,8 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
+tss2_CFLAGS = @tss2_CFLAGS@
+tss2_LIBS = @tss2_LIBS@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
@@ -451,7 +451,10 @@ AM_CFLAGS = \
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-sha3.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-sha3.la
libstrongswan_sha3_la_SOURCES = \
- sha3_plugin.h sha3_plugin.c sha3_hasher.c sha3_hasher.h
+ sha3_plugin.h sha3_plugin.c \
+ sha3_hasher.c sha3_hasher.h \
+ sha3_shake.h sha3_shake.c \
+ sha3_keccak.h sha3_keccak.c
libstrongswan_sha3_la_LDFLAGS = -module -avoid-version
all: all-am
@@ -544,7 +547,9 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha3_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha3_keccak.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha3_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha3_shake.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
diff --git a/src/libstrongswan/plugins/sha3/sha3_hasher.c b/src/libstrongswan/plugins/sha3/sha3_hasher.c
index b34a02594..0fbcbb8dc 100644
--- a/src/libstrongswan/plugins/sha3/sha3_hasher.c
+++ b/src/libstrongswan/plugins/sha3/sha3_hasher.c
@@ -1,53 +1,25 @@
/*
- * Copyright (C) 2015 Andreas Steffen
+ * Copyright (C) 2015-2016 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
- * Based on the implementation by the Keccak, Keyak and Ketje Teams, namely,
- * Guido Bertoni, Joan Daemen, Michaël Peeters, Gilles Van Assche and
- * Ronny Van Keer, hereby denoted as "the implementer".
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
- * To the extent possible under law, the implementer has waived all copyright
- * and related or neighboring rights to the source code in this file.
- * http://creativecommons.org/publicdomain/zero/1.0/
+ * This program 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 General Public License
+ * for more details.
*/
#include <string.h>
#include "sha3_hasher.h"
+#include "sha3_keccak.h"
typedef struct private_sha3_hasher_t private_sha3_hasher_t;
-#define KECCAK_STATE_SIZE 200 /* bytes */
-#define KECCAK_MAX_RATE 144 /* bytes */
-#define DELIMITED_SUFFIX 0x06
-
-static const uint64_t round_constants[] = {
- 0x0000000000000001ULL,
- 0x0000000000008082ULL,
- 0x800000000000808aULL,
- 0x8000000080008000ULL,
- 0x000000000000808bULL,
- 0x0000000080000001ULL,
- 0x8000000080008081ULL,
- 0x8000000000008009ULL,
- 0x000000000000008aULL,
- 0x0000000000000088ULL,
- 0x0000000080008009ULL,
- 0x000000008000000aULL,
- 0x000000008000808bULL,
- 0x800000000000008bULL,
- 0x8000000000008089ULL,
- 0x8000000000008003ULL,
- 0x8000000000008002ULL,
- 0x8000000000000080ULL,
- 0x000000000000800aULL,
- 0x800000008000000aULL,
- 0x8000000080008081ULL,
- 0x8000000000008080ULL,
- 0x0000000080000001ULL,
- 0x8000000080008008ULL
-};
-
/**
* Private data structure with hashing context for SHA-3
*/
@@ -64,309 +36,16 @@ struct private_sha3_hasher_t {
hash_algorithm_t algorithm;
/**
- * Internal state of 1600 bits as defined by FIPS-202
- */
- uint8_t state[KECCAK_STATE_SIZE];
-
- /**
- * Rate in bytes
+ * SHA-3 Keccak state
*/
- u_int rate;
-
- /**
- * Rate input buffer
- */
- uint8_t rate_buffer[KECCAK_MAX_RATE];
-
- /**
- * Index pointing to the current position in the rate buffer
- */
- u_int rate_index;
+ sha3_keccak_t *keccak;
};
-#if BYTE_ORDER != LITTLE_ENDIAN
-/**
- * Function to load a 64-bit value using the little-endian (LE) convention.
- * On a LE platform, this could be greatly simplified using a cast.
- */
-static uint64_t load64(const uint8_t *x)
-{
- int i;
- uint64_t u = 0;
-
- for (i = 7; i >= 0; --i)
- {
- u <<= 8;
- u |= x[i];
- }
- return u;
-}
-
-/**
- * Function to store a 64-bit value using the little-endian (LE) convention.
- * On a LE platform, this could be greatly simplified using a cast.
- */
-static void store64(uint8_t *x, uint64_t u)
-{
- u_int i;
-
- for (i = 0; i < 8; ++i)
- {
- x[i] = u;
- u >>= 8;
- }
-}
-
-/**
- * Function to XOR into a 64-bit value using the little-endian (LE) convention.
- * On a LE platform, this could be greatly simplified using a cast.
- */
-static void xor64(uint8_t *x, uint64_t u)
-{
- u_int i;
-
- for (i = 0; i < 8; ++i)
- {
- x[i] ^= u;
- u >>= 8;
- }
-}
-#endif
-
-/**
- * Some macros used by the Keccak-f[1600] permutation.
- */
-#define ROL64(a, offset) ((((uint64_t)a) << offset) ^ (((uint64_t)a) >> (64-offset)))
-
-#if BYTE_ORDER == LITTLE_ENDIAN
- #define readLane(i) (((uint64_t*)state)[i])
- #define writeLane(i, lane) (((uint64_t*)state)[i]) = (lane)
- #define XORLane(i, lane) (((uint64_t*)state)[i]) ^= (lane)
-#elif BYTE_ORDER == BIG_ENDIAN
- #define readLane(i) load64((uint8_t*)state+sizeof(uint64_t)*i))
- #define writeLane(i, lane) store64((uint8_t*)state+sizeof(uint64_t)*i, lane)
- #define XORLane(i, lane) xor64((uint8_t*)state+sizeof(uint64_t)*i, lane)
-#endif
-
-/**
- * Function that computes the Keccak-f[1600] permutation on the given state.
- */
-static void keccak_f1600_state_permute(void *state)
-{
- int round;
-
- for (round = 0; round < 24; round++)
- {
- { /* θ step (see [Keccak Reference, Section 2.3.2]) */
-
- uint64_t C[5], D;
-
- /* Compute the parity of the columns */
- C[0] = readLane(0) ^ readLane( 5) ^ readLane(10)
- ^ readLane(15) ^ readLane(20);
- C[1] = readLane(1) ^ readLane( 6) ^ readLane(11)
- ^ readLane(16) ^ readLane(21);
- C[2] = readLane(2) ^ readLane( 7) ^ readLane(12)
- ^ readLane(17) ^ readLane(22);
- C[3] = readLane(3) ^ readLane( 8) ^ readLane(13)
- ^ readLane(18) ^ readLane(23);
- C[4] = readLane(4) ^ readLane( 9) ^ readLane(14)
- ^ readLane(19) ^ readLane(24);
-
- /* Compute and add the θ effect to the whole column */
- D = C[4] ^ ROL64(C[1], 1);
- XORLane( 0, D);
- XORLane( 5, D);
- XORLane(10, D);
- XORLane(15, D);
- XORLane(20, D);
-
- D = C[0] ^ ROL64(C[2], 1);
- XORLane( 1, D);
- XORLane( 6, D);
- XORLane(11, D);
- XORLane(16, D);
- XORLane(21, D);
-
- D = C[1] ^ ROL64(C[3], 1);
- XORLane( 2, D);
- XORLane( 7, D);
- XORLane(12, D);
- XORLane(17, D);
- XORLane(22, D);
-
- D = C[2] ^ ROL64(C[4], 1);
- XORLane( 3, D);
- XORLane( 8, D);
- XORLane(13, D);
- XORLane(18, D);
- XORLane(23, D);
-
- D = C[3] ^ ROL64(C[0], 1);
- XORLane( 4, D);
- XORLane( 9, D);
- XORLane(14, D);
- XORLane(19, D);
- XORLane(24, D);
- }
-
- { /* ρ and π steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) */
-
- uint64_t t1, t2;
-
- t1 = readLane( 1);
-
- t2 = readLane(10);
- writeLane(10, ROL64(t1, 1));
-
- t1 = readLane( 7);
- writeLane( 7, ROL64(t2, 3));
-
- t2 = readLane(11);
- writeLane(11, ROL64(t1, 6));
-
- t1 = readLane(17);
- writeLane(17, ROL64(t2, 10));
-
- t2 = readLane(18);
- writeLane(18, ROL64(t1, 15));
-
- t1 = readLane( 3);
- writeLane( 3, ROL64(t2, 21));
-
- t2 = readLane( 5);
- writeLane( 5, ROL64(t1, 28));
-
- t1 = readLane(16);
- writeLane(16, ROL64(t2, 36));
-
- t2 = readLane( 8);
- writeLane( 8, ROL64(t1, 45));
-
- t1 = readLane(21);
- writeLane(21, ROL64(t2, 55));
-
- t2 = readLane(24);
- writeLane(24, ROL64(t1, 2));
-
- t1 = readLane( 4);
- writeLane( 4, ROL64(t2, 14));
-
- t2 = readLane(15);
- writeLane(15, ROL64(t1, 27));
-
- t1 = readLane(23);
- writeLane(23, ROL64(t2, 41));
-
- t2 = readLane(19);
- writeLane(19, ROL64(t1, 56));
-
- t1 = readLane(13);
- writeLane(13, ROL64(t2, 8));
-
- t2 = readLane(12);
- writeLane(12, ROL64(t1, 25));
-
- t1 = readLane( 2);
- writeLane( 2, ROL64(t2, 43));
-
- t2 = readLane(20);
- writeLane(20, ROL64(t1, 62));
-
- t1 = readLane(14);
- writeLane(14, ROL64(t2, 18));
-
- t2 = readLane(22);
- writeLane(22, ROL64(t1, 39));
-
- t1 = readLane( 9);
- writeLane( 9, ROL64(t2, 61));
-
- t2 = readLane( 6);
- writeLane( 6, ROL64(t1, 20));
-
- writeLane( 1, ROL64(t2, 44));
- }
-
- { /* χ step (see [Keccak Reference, Section 2.3.1]) */
-
- uint64_t t[5];
-
- t[0] = readLane(0);
- t[1] = readLane(1);
- t[2] = readLane(2);
- t[3] = readLane(3);
- t[4] = readLane(4);
-
- writeLane(0, t[0] ^ ((~t[1]) & t[2]));
- writeLane(1, t[1] ^ ((~t[2]) & t[3]));
- writeLane(2, t[2] ^ ((~t[3]) & t[4]));
- writeLane(3, t[3] ^ ((~t[4]) & t[0]));
- writeLane(4, t[4] ^ ((~t[0]) & t[1]));
-
- t[0] = readLane(5);
- t[1] = readLane(6);
- t[2] = readLane(7);
- t[3] = readLane(8);
- t[4] = readLane(9);
-
- writeLane(5, t[0] ^ ((~t[1]) & t[2]));
- writeLane(6, t[1] ^ ((~t[2]) & t[3]));
- writeLane(7, t[2] ^ ((~t[3]) & t[4]));
- writeLane(8, t[3] ^ ((~t[4]) & t[0]));
- writeLane(9, t[4] ^ ((~t[0]) & t[1]));
-
- t[0] = readLane(10);
- t[1] = readLane(11);
- t[2] = readLane(12);
- t[3] = readLane(13);
- t[4] = readLane(14);
-
- writeLane(10, t[0] ^ ((~t[1]) & t[2]));
- writeLane(11, t[1] ^ ((~t[2]) & t[3]));
- writeLane(12, t[2] ^ ((~t[3]) & t[4]));
- writeLane(13, t[3] ^ ((~t[4]) & t[0]));
- writeLane(14, t[4] ^ ((~t[0]) & t[1]));
-
- t[0] = readLane(15);
- t[1] = readLane(16);
- t[2] = readLane(17);
- t[3] = readLane(18);
- t[4] = readLane(19);
-
- writeLane(15, t[0] ^ ((~t[1]) & t[2]));
- writeLane(16, t[1] ^ ((~t[2]) & t[3]));
- writeLane(17, t[2] ^ ((~t[3]) & t[4]));
- writeLane(18, t[3] ^ ((~t[4]) & t[0]));
- writeLane(19, t[4] ^ ((~t[0]) & t[1]));
-
- t[0] = readLane(20);
- t[1] = readLane(21);
- t[2] = readLane(22);
- t[3] = readLane(23);
- t[4] = readLane(24);
-
- writeLane(20, t[0] ^ ((~t[1]) & t[2]));
- writeLane(21, t[1] ^ ((~t[2]) & t[3]));
- writeLane(22, t[2] ^ ((~t[3]) & t[4]));
- writeLane(23, t[3] ^ ((~t[4]) & t[0]));
- writeLane(24, t[4] ^ ((~t[0]) & t[1]));
- }
-
- { /* ι step (see [Keccak Reference, Section 2.3.5]) */
-
- XORLane(0, round_constants[round]);
- }
- }
-}
-
METHOD(hasher_t, reset, bool,
private_sha3_hasher_t *this)
{
- memset(this->state, 0x00, KECCAK_STATE_SIZE);
- this->rate_index = 0;
-
+ this->keccak->reset(this->keccak);
return TRUE;
}
@@ -388,79 +67,17 @@ METHOD(hasher_t, get_hash_size, size_t,
}
}
-static void sha3_absorb(private_sha3_hasher_t *this, chunk_t data)
-{
- uint64_t *buffer_lanes, *state_lanes;
- size_t len, rate_lanes;
- int i;
-
- buffer_lanes = (uint64_t*)this->rate_buffer;
- state_lanes = (uint64_t*)this->state;
- rate_lanes = this->rate / sizeof(uint64_t);
-
- while (data.len)
- {
- len = min(data.len, this->rate - this->rate_index);
- memcpy(this->rate_buffer + this->rate_index, data.ptr, len);
- this->rate_index += len;
- data.ptr += len;
- data.len -= len;
-
- if (this->rate_index == this->rate)
- {
- for (i = 0; i < rate_lanes; i++)
- {
- state_lanes[i] ^= buffer_lanes[i];
- }
- this->rate_index = 0;
-
- keccak_f1600_state_permute(this->state);
- }
- }
-}
-
-static void sha3_final(private_sha3_hasher_t *this)
-{
- uint64_t *buffer_lanes, *state_lanes;
- size_t rate_lanes, remainder;
- int i;
-
- /* Add the delimitedSuffix as the first bit of padding */
- this->rate_buffer[this->rate_index++] = DELIMITED_SUFFIX;
-
- buffer_lanes = (uint64_t*)this->rate_buffer;
- state_lanes = (uint64_t*)this->state;
- rate_lanes = this->rate_index / sizeof(uint64_t);
-
- remainder = this->rate_index - rate_lanes * sizeof(uint64_t);
- if (remainder)
- {
- memset(this->rate_buffer + this->rate_index, 0x00,
- sizeof(uint64_t) - remainder);
- rate_lanes++;
- }
- for (i = 0; i < rate_lanes; i++)
- {
- state_lanes[i] ^= buffer_lanes[i];
- }
-
- /* Add the second bit of padding */
- this->state[this->rate - 1] ^= 0x80;
-
- /* Switch to the squeezing phase */
- keccak_f1600_state_permute(this->state);
-}
METHOD(hasher_t, get_hash, bool,
private_sha3_hasher_t *this, chunk_t chunk, uint8_t *buffer)
{
- sha3_absorb(this, chunk);
+ this->keccak->absorb(this->keccak, chunk);
if (buffer != NULL)
{
- sha3_final(this);
- memcpy(buffer, this->state, get_hash_size(this));
- reset(this);
+ this->keccak->finalize(this->keccak);
+ this->keccak->squeeze(this->keccak, get_hash_size(this), buffer);
+ this->keccak->reset(this->keccak);
}
return TRUE;
}
@@ -470,22 +87,24 @@ METHOD(hasher_t, allocate_hash, bool,
{
chunk_t allocated_hash;
- sha3_absorb(this, chunk);
+ this->keccak->absorb(this->keccak, chunk);
if (hash != NULL)
{
- sha3_final(this);
+ this->keccak->finalize(this->keccak);
allocated_hash = chunk_alloc(get_hash_size(this));
- memcpy(allocated_hash.ptr, this->state, allocated_hash.len);
- reset(this);
+ this->keccak->squeeze(this->keccak, allocated_hash.len,
+ allocated_hash.ptr);
+ this->keccak->reset(this->keccak);
*hash = allocated_hash;
}
return TRUE;
}
METHOD(hasher_t, destroy, void,
- sha3_hasher_t *this)
+ private_sha3_hasher_t *this)
{
+ this->keccak->destroy(this->keccak);
free(this);
}
@@ -510,18 +129,22 @@ sha3_hasher_t *sha3_hasher_create(hash_algorithm_t algorithm)
INIT(this,
.public = {
.hasher_interface = {
- .reset = _reset,
- .get_hash_size = _get_hash_size,
- .get_hash = _get_hash,
- .allocate_hash = _allocate_hash,
- .destroy = _destroy,
+ .reset = _reset,
+ .get_hash_size = _get_hash_size,
+ .get_hash = _get_hash,
+ .allocate_hash = _allocate_hash,
+ .destroy = _destroy,
},
},
.algorithm = algorithm,
);
- this->rate = KECCAK_STATE_SIZE - 2*get_hash_size(this);
- reset(this);
+ this->keccak = sha3_keccak_create(2*get_hash_size(this), 0x06);
+ if (!this->keccak)
+ {
+ free(this);
+ return NULL;
+ }
return &this->public;
}
diff --git a/src/libstrongswan/plugins/sha3/sha3_keccak.c b/src/libstrongswan/plugins/sha3/sha3_keccak.c
new file mode 100644
index 000000000..1be1db160
--- /dev/null
+++ b/src/libstrongswan/plugins/sha3/sha3_keccak.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright (C) 2015-2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Based on the implementation by the Keccak, Keyak and Ketje Teams, namely,
+ * Guido Bertoni, Joan Daemen, Michaël Peeters, Gilles Van Assche and
+ * Ronny Van Keer, hereby denoted as "the implementer".
+ *
+ * To the extent possible under law, the implementer has waived all copyright
+ * and related or neighboring rights to the source code in this file.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+#include <string.h>
+
+#include "sha3_keccak.h"
+
+typedef struct private_sha3_keccak_t private_sha3_keccak_t;
+
+#define KECCAK_STATE_SIZE 200 /* bytes */
+#define KECCAK_MAX_RATE 168 /* bytes */
+
+static const uint64_t round_constants[] = {
+ 0x0000000000000001ULL,
+ 0x0000000000008082ULL,
+ 0x800000000000808aULL,
+ 0x8000000080008000ULL,
+ 0x000000000000808bULL,
+ 0x0000000080000001ULL,
+ 0x8000000080008081ULL,
+ 0x8000000000008009ULL,
+ 0x000000000000008aULL,
+ 0x0000000000000088ULL,
+ 0x0000000080008009ULL,
+ 0x000000008000000aULL,
+ 0x000000008000808bULL,
+ 0x800000000000008bULL,
+ 0x8000000000008089ULL,
+ 0x8000000000008003ULL,
+ 0x8000000000008002ULL,
+ 0x8000000000000080ULL,
+ 0x000000000000800aULL,
+ 0x800000008000000aULL,
+ 0x8000000080008081ULL,
+ 0x8000000000008080ULL,
+ 0x0000000080000001ULL,
+ 0x8000000080008008ULL
+};
+
+/**
+ * Private data structure with hashing context for SHA-3
+ */
+struct private_sha3_keccak_t {
+
+ /**
+ * Public interface for this hasher.
+ */
+ sha3_keccak_t public;
+
+ /**
+ * Internal state of 1600 bits as defined by FIPS-202
+ */
+ uint8_t state[KECCAK_STATE_SIZE];
+
+ /**
+ * Rate in bytes
+ */
+ u_int rate;
+
+ /**
+ * Rate input buffer
+ */
+ uint8_t rate_buffer[KECCAK_MAX_RATE];
+
+ /**
+ * Index pointing to the current position in the rate buffer
+ */
+ u_int rate_index;
+
+ /**
+ * Suffix delimiting the input message
+ */
+ uint8_t delimited_suffix;
+
+};
+
+#if BYTE_ORDER != LITTLE_ENDIAN
+/**
+ * Function to load a 64-bit value using the little-endian (LE) convention.
+ * On a LE platform, this could be greatly simplified using a cast.
+ */
+static uint64_t load64(const uint8_t *x)
+{
+ int i;
+ uint64_t u = 0;
+
+ for (i = 7; i >= 0; --i)
+ {
+ u <<= 8;
+ u |= x[i];
+ }
+ return u;
+}
+
+/**
+ * Function to store a 64-bit value using the little-endian (LE) convention.
+ * On a LE platform, this could be greatly simplified using a cast.
+ */
+static void store64(uint8_t *x, uint64_t u)
+{
+ u_int i;
+
+ for (i = 0; i < 8; ++i)
+ {
+ x[i] = u;
+ u >>= 8;
+ }
+}
+
+/**
+ * Function to XOR into a 64-bit value using the little-endian (LE) convention.
+ * On a LE platform, this could be greatly simplified using a cast.
+ */
+static void xor64(uint8_t *x, uint64_t u)
+{
+ u_int i;
+
+ for (i = 0; i < 8; ++i)
+ {
+ x[i] ^= u;
+ u >>= 8;
+ }
+}
+#endif
+
+/**
+ * Some macros used by the Keccak-f[1600] permutation.
+ */
+#define ROL64(a, offset) ((((uint64_t)a) << offset) ^ (((uint64_t)a) >> (64-offset)))
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ #define readLane(i) (((uint64_t*)state)[i])
+ #define writeLane(i, lane) (((uint64_t*)state)[i]) = (lane)
+ #define XORLane(i, lane) (((uint64_t*)state)[i]) ^= (lane)
+#elif BYTE_ORDER == BIG_ENDIAN
+ #define readLane(i) load64((uint8_t*)state+sizeof(uint64_t)*i))
+ #define writeLane(i, lane) store64((uint8_t*)state+sizeof(uint64_t)*i, lane)
+ #define XORLane(i, lane) xor64((uint8_t*)state+sizeof(uint64_t)*i, lane)
+#endif
+
+/**
+ * Function that computes the Keccak-f[1600] permutation on the given state.
+ */
+static void keccak_f1600_state_permute(void *state)
+{
+ int round;
+
+ for (round = 0; round < 24; round++)
+ {
+ { /* θ step (see [Keccak Reference, Section 2.3.2]) */
+
+ uint64_t C[5], D;
+
+ /* Compute the parity of the columns */
+ C[0] = readLane(0) ^ readLane( 5) ^ readLane(10)
+ ^ readLane(15) ^ readLane(20);
+ C[1] = readLane(1) ^ readLane( 6) ^ readLane(11)
+ ^ readLane(16) ^ readLane(21);
+ C[2] = readLane(2) ^ readLane( 7) ^ readLane(12)
+ ^ readLane(17) ^ readLane(22);
+ C[3] = readLane(3) ^ readLane( 8) ^ readLane(13)
+ ^ readLane(18) ^ readLane(23);
+ C[4] = readLane(4) ^ readLane( 9) ^ readLane(14)
+ ^ readLane(19) ^ readLane(24);
+
+ /* Compute and add the θ effect to the whole column */
+ D = C[4] ^ ROL64(C[1], 1);
+ XORLane( 0, D);
+ XORLane( 5, D);
+ XORLane(10, D);
+ XORLane(15, D);
+ XORLane(20, D);
+
+ D = C[0] ^ ROL64(C[2], 1);
+ XORLane( 1, D);
+ XORLane( 6, D);
+ XORLane(11, D);
+ XORLane(16, D);
+ XORLane(21, D);
+
+ D = C[1] ^ ROL64(C[3], 1);
+ XORLane( 2, D);
+ XORLane( 7, D);
+ XORLane(12, D);
+ XORLane(17, D);
+ XORLane(22, D);
+
+ D = C[2] ^ ROL64(C[4], 1);
+ XORLane( 3, D);
+ XORLane( 8, D);
+ XORLane(13, D);
+ XORLane(18, D);
+ XORLane(23, D);
+
+ D = C[3] ^ ROL64(C[0], 1);
+ XORLane( 4, D);
+ XORLane( 9, D);
+ XORLane(14, D);
+ XORLane(19, D);
+ XORLane(24, D);
+ }
+
+ { /* ρ and π steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) */
+
+ uint64_t t1, t2;
+
+ t1 = readLane( 1);
+
+ t2 = readLane(10);
+ writeLane(10, ROL64(t1, 1));
+
+ t1 = readLane( 7);
+ writeLane( 7, ROL64(t2, 3));
+
+ t2 = readLane(11);
+ writeLane(11, ROL64(t1, 6));
+
+ t1 = readLane(17);
+ writeLane(17, ROL64(t2, 10));
+
+ t2 = readLane(18);
+ writeLane(18, ROL64(t1, 15));
+
+ t1 = readLane( 3);
+ writeLane( 3, ROL64(t2, 21));
+
+ t2 = readLane( 5);
+ writeLane( 5, ROL64(t1, 28));
+
+ t1 = readLane(16);
+ writeLane(16, ROL64(t2, 36));
+
+ t2 = readLane( 8);
+ writeLane( 8, ROL64(t1, 45));
+
+ t1 = readLane(21);
+ writeLane(21, ROL64(t2, 55));
+
+ t2 = readLane(24);
+ writeLane(24, ROL64(t1, 2));
+
+ t1 = readLane( 4);
+ writeLane( 4, ROL64(t2, 14));
+
+ t2 = readLane(15);
+ writeLane(15, ROL64(t1, 27));
+
+ t1 = readLane(23);
+ writeLane(23, ROL64(t2, 41));
+
+ t2 = readLane(19);
+ writeLane(19, ROL64(t1, 56));
+
+ t1 = readLane(13);
+ writeLane(13, ROL64(t2, 8));
+
+ t2 = readLane(12);
+ writeLane(12, ROL64(t1, 25));
+
+ t1 = readLane( 2);
+ writeLane( 2, ROL64(t2, 43));
+
+ t2 = readLane(20);
+ writeLane(20, ROL64(t1, 62));
+
+ t1 = readLane(14);
+ writeLane(14, ROL64(t2, 18));
+
+ t2 = readLane(22);
+ writeLane(22, ROL64(t1, 39));
+
+ t1 = readLane( 9);
+ writeLane( 9, ROL64(t2, 61));
+
+ t2 = readLane( 6);
+ writeLane( 6, ROL64(t1, 20));
+
+ writeLane( 1, ROL64(t2, 44));
+ }
+
+ { /* χ step (see [Keccak Reference, Section 2.3.1]) */
+
+ uint64_t t[5];
+
+ t[0] = readLane(0);
+ t[1] = readLane(1);
+ t[2] = readLane(2);
+ t[3] = readLane(3);
+ t[4] = readLane(4);
+
+ writeLane(0, t[0] ^ ((~t[1]) & t[2]));
+ writeLane(1, t[1] ^ ((~t[2]) & t[3]));
+ writeLane(2, t[2] ^ ((~t[3]) & t[4]));
+ writeLane(3, t[3] ^ ((~t[4]) & t[0]));
+ writeLane(4, t[4] ^ ((~t[0]) & t[1]));
+
+ t[0] = readLane(5);
+ t[1] = readLane(6);
+ t[2] = readLane(7);
+ t[3] = readLane(8);
+ t[4] = readLane(9);
+
+ writeLane(5, t[0] ^ ((~t[1]) & t[2]));
+ writeLane(6, t[1] ^ ((~t[2]) & t[3]));
+ writeLane(7, t[2] ^ ((~t[3]) & t[4]));
+ writeLane(8, t[3] ^ ((~t[4]) & t[0]));
+ writeLane(9, t[4] ^ ((~t[0]) & t[1]));
+
+ t[0] = readLane(10);
+ t[1] = readLane(11);
+ t[2] = readLane(12);
+ t[3] = readLane(13);
+ t[4] = readLane(14);
+
+ writeLane(10, t[0] ^ ((~t[1]) & t[2]));
+ writeLane(11, t[1] ^ ((~t[2]) & t[3]));
+ writeLane(12, t[2] ^ ((~t[3]) & t[4]));
+ writeLane(13, t[3] ^ ((~t[4]) & t[0]));
+ writeLane(14, t[4] ^ ((~t[0]) & t[1]));
+
+ t[0] = readLane(15);
+ t[1] = readLane(16);
+ t[2] = readLane(17);
+ t[3] = readLane(18);
+ t[4] = readLane(19);
+
+ writeLane(15, t[0] ^ ((~t[1]) & t[2]));
+ writeLane(16, t[1] ^ ((~t[2]) & t[3]));
+ writeLane(17, t[2] ^ ((~t[3]) & t[4]));
+ writeLane(18, t[3] ^ ((~t[4]) & t[0]));
+ writeLane(19, t[4] ^ ((~t[0]) & t[1]));
+
+ t[0] = readLane(20);
+ t[1] = readLane(21);
+ t[2] = readLane(22);
+ t[3] = readLane(23);
+ t[4] = readLane(24);
+
+ writeLane(20, t[0] ^ ((~t[1]) & t[2]));
+ writeLane(21, t[1] ^ ((~t[2]) & t[3]));
+ writeLane(22, t[2] ^ ((~t[3]) & t[4]));
+ writeLane(23, t[3] ^ ((~t[4]) & t[0]));
+ writeLane(24, t[4] ^ ((~t[0]) & t[1]));
+ }
+
+ { /* ι step (see [Keccak Reference, Section 2.3.5]) */
+
+ XORLane(0, round_constants[round]);
+ }
+ }
+}
+
+METHOD(sha3_keccak_t, get_rate, u_int,
+ private_sha3_keccak_t *this)
+{
+ return this->rate;
+}
+
+METHOD(sha3_keccak_t, reset, void,
+ private_sha3_keccak_t *this)
+{
+ memset(this->state, 0x00, KECCAK_STATE_SIZE);
+ this->rate_index = 0;
+}
+
+
+METHOD(sha3_keccak_t, absorb, void,
+ private_sha3_keccak_t *this, chunk_t data)
+{
+ uint64_t *buffer_lanes, *state_lanes;
+ size_t len, rate_lanes;
+ int i;
+
+ buffer_lanes = (uint64_t*)this->rate_buffer;
+ state_lanes = (uint64_t*)this->state;
+ rate_lanes = this->rate / sizeof(uint64_t);
+
+ while (data.len)
+ {
+ len = min(data.len, this->rate - this->rate_index);
+ memcpy(this->rate_buffer + this->rate_index, data.ptr, len);
+ this->rate_index += len;
+ data.ptr += len;
+ data.len -= len;
+
+ if (this->rate_index == this->rate)
+ {
+ for (i = 0; i < rate_lanes; i++)
+ {
+ state_lanes[i] ^= buffer_lanes[i];
+ }
+ this->rate_index = 0;
+
+ keccak_f1600_state_permute(this->state);
+ }
+ }
+}
+
+METHOD(sha3_keccak_t, finalize, void,
+ private_sha3_keccak_t *this)
+{
+ uint64_t *buffer_lanes, *state_lanes;
+ size_t rate_lanes, remainder;
+ int i;
+
+ /* Add the delimitedSuffix as the first bit of padding */
+ this->rate_buffer[this->rate_index++] = this->delimited_suffix;
+
+ buffer_lanes = (uint64_t*)this->rate_buffer;
+ state_lanes = (uint64_t*)this->state;
+ rate_lanes = this->rate_index / sizeof(uint64_t);
+
+ remainder = this->rate_index - rate_lanes * sizeof(uint64_t);
+ if (remainder)
+ {
+ memset(this->rate_buffer + this->rate_index, 0x00,
+ sizeof(uint64_t) - remainder);
+ rate_lanes++;
+ }
+ for (i = 0; i < rate_lanes; i++)
+ {
+ state_lanes[i] ^= buffer_lanes[i];
+ }
+
+ /* Add the second bit of padding */
+ this->state[this->rate - 1] ^= 0x80;
+
+ /* Switch to the squeezing phase */
+ keccak_f1600_state_permute(this->state);
+ this->rate_index = 0;
+}
+
+METHOD(sha3_keccak_t, squeeze, void,
+ private_sha3_keccak_t *this, size_t out_len, uint8_t *out)
+{
+ size_t index = 0, len;
+
+ while (index < out_len)
+ {
+ if (this->rate_index == this->rate)
+ {
+ keccak_f1600_state_permute(this->state);
+ this->rate_index = 0;
+ }
+ len = min(out_len - index, this->rate - this->rate_index);
+ memcpy(out, &this->state[this->rate_index], len);
+ out += len;
+ index += len;
+ this->rate_index += len;
+ }
+}
+
+METHOD(sha3_keccak_t, destroy, void,
+ private_sha3_keccak_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+sha3_keccak_t *sha3_keccak_create(u_int capacity, uint8_t delimited_suffix)
+{
+ private_sha3_keccak_t *this;
+ int rate;
+
+ rate = KECCAK_STATE_SIZE - capacity;
+
+ if (rate <= 0 || rate > KECCAK_MAX_RATE)
+ {
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .get_rate = _get_rate,
+ .reset = _reset,
+ .absorb = _absorb,
+ .finalize = _finalize,
+ .squeeze = _squeeze,
+ .destroy = _destroy,
+ },
+ .rate = rate,
+ .delimited_suffix = delimited_suffix,
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/sha3/sha3_keccak.h b/src/libstrongswan/plugins/sha3/sha3_keccak.h
new file mode 100644
index 000000000..eeea9d7fd
--- /dev/null
+++ b/src/libstrongswan/plugins/sha3/sha3_keccak.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+n */
+
+/**
+ * @defgroup sha3_keccak sha3_keccak
+ * @{ @ingroup sha3_p
+ */
+
+#ifndef SHA3_KECCAK_H_
+#define SHA3_KECCAK_H_
+
+typedef struct sha3_keccak_t sha3_keccak_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Implements the Keccak-f[1600] sponge function as defined by FIPS-202.
+ */
+struct sha3_keccak_t {
+
+ /**
+ * Get the available rate in bytes
+ *
+ * @return rate in bytes
+ */
+ u_int (*get_rate)(sha3_keccak_t *this);
+
+ /**
+ * Resets the internal Keccak state
+ */
+ void (*reset)(sha3_keccak_t *this);
+
+ /**
+ * Absorbs data into the Keccak state
+ *
+ * @param data data to be absorbed
+ */
+ void (*absorb)(sha3_keccak_t *this, chunk_t data);
+
+ /**
+ * Finalize the absorption phase and switch to the squeeze phase
+ */
+ void (*finalize)(sha3_keccak_t *this);
+
+ /**
+ * Squeeze the Keccak state to get output data
+ * Can be called multiple times
+ *
+ * @param out_len number of output bytes requested
+ * @param out output buffer, must comprise at least out_len bytes
+ */
+ void (*squeeze)(sha3_keccak_t *this, size_t out_len, uint8_t *out);
+
+ /**
+ * Destroy the sha3_keccak_t object
+ */
+ void (*destroy)(sha3_keccak_t *this);
+
+};
+
+/**
+ * Creates a new sha3_keccak_t.
+ *
+ * @param capacity required capacity to achieve a given security level
+ * @param delimited_suffix bits delimiting the input message
+ * @return sha3_keccak_t object, NULL if capacity too big
+ */
+sha3_keccak_t *sha3_keccak_create(u_int capacity, uint8_t delimited_suffix);
+
+#endif /** SHA3_KECCAK_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha3/sha3_plugin.c b/src/libstrongswan/plugins/sha3/sha3_plugin.c
index 28068f38e..8268e67c3 100644
--- a/src/libstrongswan/plugins/sha3/sha3_plugin.c
+++ b/src/libstrongswan/plugins/sha3/sha3_plugin.c
@@ -14,9 +14,10 @@
*/
#include "sha3_plugin.h"
+#include "sha3_hasher.h"
+#include "sha3_shake.h"
#include <library.h>
-#include "sha3_hasher.h"
typedef struct private_sha3_plugin_t private_sha3_plugin_t;
@@ -46,6 +47,9 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(HASHER, HASH_SHA3_256),
PLUGIN_PROVIDE(HASHER, HASH_SHA3_384),
PLUGIN_PROVIDE(HASHER, HASH_SHA3_512),
+ PLUGIN_REGISTER(XOF, sha3_shake_create),
+ PLUGIN_PROVIDE(XOF, XOF_SHAKE_128),
+ PLUGIN_PROVIDE(XOF, XOF_SHAKE_256),
};
*features = f;
return countof(f);
diff --git a/src/libstrongswan/plugins/sha3/sha3_shake.c b/src/libstrongswan/plugins/sha3/sha3_shake.c
new file mode 100644
index 000000000..0f1af39f5
--- /dev/null
+++ b/src/libstrongswan/plugins/sha3/sha3_shake.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+#include "sha3_shake.h"
+#include "sha3_keccak.h"
+
+typedef struct private_sha3_shake_t private_sha3_shake_t;
+
+
+/**
+ * Private data structure with hashing context for SHA-3
+ */
+struct private_sha3_shake_t {
+
+ /**
+ * Public interface for this hasher.
+ */
+ sha3_shake_t public;
+
+ /**
+ * XOF algorithm to be used (XOF_SHAKE_128 or XOF_SHAKE_256)
+ */
+ ext_out_function_t algorithm;
+
+ /**
+ * SHA-3 Keccak state
+ */
+ sha3_keccak_t *keccak;
+
+ /**
+ * Capacity in bytes of the SHA-3 Keccak state
+ */
+ u_int capacity;
+
+};
+
+METHOD(xof_t, get_type, ext_out_function_t,
+ private_sha3_shake_t *this)
+{
+ return this->algorithm;
+}
+
+METHOD(xof_t, get_bytes, bool,
+ private_sha3_shake_t *this, size_t out_len, uint8_t *buffer)
+{
+ this->keccak->squeeze(this->keccak, out_len, buffer);
+ return TRUE;
+}
+
+METHOD(xof_t, allocate_bytes, bool,
+ private_sha3_shake_t *this, size_t out_len, chunk_t *chunk)
+{
+ *chunk = chunk_alloc(out_len);
+ this->keccak->squeeze(this->keccak, out_len, chunk->ptr);
+ return TRUE;
+}
+
+METHOD(xof_t, get_block_size, size_t,
+ private_sha3_shake_t *this)
+{
+ return this->keccak->get_rate(this->keccak);
+}
+
+METHOD(xof_t, get_seed_size, size_t,
+ private_sha3_shake_t *this)
+{
+ return this->capacity;
+}
+
+METHOD(xof_t, set_seed, bool,
+ private_sha3_shake_t *this, chunk_t seed)
+{
+ this->keccak->reset(this->keccak);
+ this->keccak->absorb(this->keccak, seed);
+ this->keccak->finalize(this->keccak);
+ return TRUE;
+}
+
+
+METHOD(xof_t, destroy, void,
+ private_sha3_shake_t *this)
+{
+ this->keccak->destroy(this->keccak);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+sha3_shake_t* sha3_shake_create(ext_out_function_t algorithm)
+{
+ private_sha3_shake_t *this;
+ u_int capacity = 0;
+
+ switch (algorithm)
+ {
+ case XOF_SHAKE_128:
+ capacity = 32;
+ break;
+ case XOF_SHAKE_256:
+ capacity = 64;
+ break;
+ default:
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .xof_interface = {
+ .get_type = _get_type,
+ .get_bytes = _get_bytes,
+ .allocate_bytes = _allocate_bytes,
+ .get_block_size = _get_block_size,
+ .get_seed_size = _get_seed_size,
+ .set_seed = _set_seed,
+ .destroy = _destroy,
+ },
+ },
+ .algorithm = algorithm,
+ .capacity = capacity,
+ );
+
+ this->keccak = sha3_keccak_create(capacity, 0x1f);
+ if (!this->keccak)
+ {
+ free(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/sha3/sha3_shake.h b/src/libstrongswan/plugins/sha3/sha3_shake.h
new file mode 100644
index 000000000..a8643edd7
--- /dev/null
+++ b/src/libstrongswan/plugins/sha3/sha3_shake.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup sha3_shake sha3_shake
+ * @{ @ingroup sha3_p
+ */
+
+#ifndef SHA3_SHAKE_H_
+#define SHA3_SHAKE_H_
+
+typedef struct sha3_shake_t sha3_shake_t;
+
+#include <crypto/xofs/xof.h>
+
+/**
+ * Implementation of xof_t interface using the SHA-3 XOF algorithm family
+ * SHAKE128 and SHAKE256 as defined by FIPS-202.
+ */
+struct sha3_shake_t {
+
+ /**
+ * Generic xof_t interface for this Extended Output Function (XOF).
+ */
+ xof_t xof_interface;
+};
+
+/**
+ * Creates a new sha3_shake_t.
+ *
+ * @param algorithm XOF_SHAKE_128 or XOF_SHAKE_256
+ * @return sha3_shake_t object, NULL if not supported
+ */
+sha3_shake_t* sha3_shake_create(ext_out_function_t algorithm);
+
+#endif /** SHA3_SHAKE_H_ @}*/