From f412c97648879b21422b163b8705197775657b06 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Fri, 19 Mar 2021 07:18:59 +0100 Subject: [PATCH] wolfssl: Support SHAKE_256 --- src/libstrongswan/plugins/wolfssl/Makefile.am | 3 +- .../plugins/wolfssl/wolfssl_plugin.c | 5 + .../plugins/wolfssl/wolfssl_xof.c | 151 ++++++++++++++++++ .../plugins/wolfssl/wolfssl_xof.h | 35 ++++ 4 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 src/libstrongswan/plugins/wolfssl/wolfssl_xof.c create mode 100644 src/libstrongswan/plugins/wolfssl/wolfssl_xof.h diff --git a/src/libstrongswan/plugins/wolfssl/Makefile.am b/src/libstrongswan/plugins/wolfssl/Makefile.am index 1f31bf613..350c3a361 100644 --- a/src/libstrongswan/plugins/wolfssl/Makefile.am +++ b/src/libstrongswan/plugins/wolfssl/Makefile.am @@ -29,7 +29,8 @@ libstrongswan_wolfssl_la_SOURCES = \ wolfssl_rng.h wolfssl_rng.c \ wolfssl_sha1_prf.h wolfssl_sha1_prf.c \ wolfssl_x_diffie_hellman.h wolfssl_x_diffie_hellman.c \ - wolfssl_util.h wolfssl_util.c + wolfssl_util.h wolfssl_util.c \ + wolfssl_xof.h wolfssl_xof.c libstrongswan_wolfssl_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c index 64fb71c2a..83ba4f380 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c @@ -41,6 +41,7 @@ #include "wolfssl_rng.h" #include "wolfssl_sha1_prf.h" #include "wolfssl_x_diffie_hellman.h" +#include "wolfssl_xof.h" #ifndef FIPS_MODE #define FIPS_MODE 0 @@ -131,6 +132,10 @@ METHOD(plugin_t, get_features, int, #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512) PLUGIN_PROVIDE(HASHER, HASH_SHA3_512), #endif +#if defined(WOLFSSL_SHAKE256) && LIBWOLFSSL_VERSION_HEX >= 0x04007001 + PLUGIN_REGISTER(XOF, wolfssl_xof_create), + PLUGIN_PROVIDE(XOF, XOF_SHAKE_256), +#endif #ifndef NO_SHA /* keyed sha1 hasher (aka prf) */ PLUGIN_REGISTER(PRF, wolfssl_sha1_prf_create), diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_xof.c b/src/libstrongswan/plugins/wolfssl/wolfssl_xof.c new file mode 100644 index 000000000..f25c524dc --- /dev/null +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_xof.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2021 Andreas Steffen, strongSec GmbH + * + * 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 . + * + * 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 + +#ifdef WOLFSSL_SHAKE256 + +#include + +#include "wolfssl_xof.h" + +#define KECCAK_STATE_SIZE 200 /* 1600 bits */ +#define SHAKE256_CAPACITY 64 /* 512 bits */ + +typedef struct private_xof_t private_xof_t; + +/** + * Private data + */ +struct private_xof_t { + + /** + * Public interface. + */ + xof_t public; + + /** + * Internal context + */ + wc_Shake shake; + + /** + * Current seed + */ + chunk_t seed; + + /** + * Offset into generated data + */ + size_t offset; +}; + +METHOD(xof_t, get_type, ext_out_function_t, + private_xof_t *this) +{ + return XOF_SHAKE_256; +} + +METHOD(xof_t, get_bytes, bool, + private_xof_t *this, size_t out_len, uint8_t *buffer) +{ + bool success = FALSE; + chunk_t data; + + /* we can call wc_Shake256_Final() only once, so to support an arbitrary + * number of calls to get_bytes(), we request all the data we already + * requested previously and just ignore what we already handed out */ + if (wc_Shake256_Update(&this->shake, this->seed.ptr, this->seed.len) == 0) + { + data = chunk_alloc(out_len + this->offset); + if (wc_Shake256_Final(&this->shake, data.ptr, data.len) == 0) + { + memcpy(buffer, data.ptr + this->offset, out_len); + this->offset += out_len; + success = TRUE; + } + chunk_clear(&data); + } + return success; +} + +METHOD(xof_t, allocate_bytes, bool, + private_xof_t *this, size_t out_len, chunk_t *chunk) +{ + *chunk = chunk_alloc(out_len); + return get_bytes(this, out_len, chunk->ptr); +} + +METHOD(xof_t, get_block_size, size_t, + private_xof_t *this) +{ + return KECCAK_STATE_SIZE - SHAKE256_CAPACITY; +} + +METHOD(xof_t, get_seed_size, size_t, + private_xof_t *this) +{ + return SHAKE256_CAPACITY; +} + +METHOD(xof_t, set_seed, bool, + private_xof_t *this, chunk_t seed) +{ + chunk_clear(&this->seed); + this->seed = chunk_clone(seed); + this->offset = 0; + return TRUE; +} + +METHOD(xof_t, destroy, void, + private_xof_t *this) +{ + wc_Shake256_Free(&this->shake); + chunk_clear(&this->seed); + free(this); +} + +/* + * Described in header + */ +xof_t *wolfssl_xof_create(ext_out_function_t algorithm) +{ + private_xof_t *this; + + if (algorithm != XOF_SHAKE_256) + { + return NULL; + } + + INIT(this, + .public = { + .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, + }, + ); + + if (wc_InitShake256(&this->shake, NULL, 0) != 0) + { + free(this); + } + + return &this->public; +} + +#endif /* WOLFSSL_SHAKE256 */ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_xof.h b/src/libstrongswan/plugins/wolfssl/wolfssl_xof.h new file mode 100644 index 000000000..cb8d25479 --- /dev/null +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_xof.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 Andreas Steffen, strongSec GmbH + * + * 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 . + * + * 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. + */ + +/** + * Implementation of the SHAKE128/256 XOF algorithm using OpenSSL. + * + * @defgroup wolfssl_xof wolfssl_xof + * @{ @ingroup wolfssl_p + */ + +#ifndef WOLFSSL_XOF_H_ +#define WOLFSSL_XOF_H_ + +#include + +/** + * Creates a new xof_t object. + * + * @param algorithm XOF algorithm to create + * @return object, NULL if not supported + */ +xof_t *wolfssl_xof_create(ext_out_function_t algorithm); + +#endif /** WOLFSSL_XOF_H_ @}*/