openssl: Add support for SHAKE128/256
authorTobias Brunner <tobias@strongswan.org>
Tue, 10 Mar 2020 11:16:26 +0000 (12:16 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 10 Mar 2020 13:12:34 +0000 (14:12 +0100)
src/libstrongswan/plugins/openssl/Makefile.am
src/libstrongswan/plugins/openssl/openssl_plugin.c
src/libstrongswan/plugins/openssl/openssl_xof.c [new file with mode: 0644]
src/libstrongswan/plugins/openssl/openssl_xof.h [new file with mode: 0644]

index 7b83890..f488bc1 100644 (file)
@@ -32,7 +32,8 @@ libstrongswan_openssl_la_SOURCES = \
        openssl_aead.c openssl_aead.h \
        openssl_x_diffie_hellman.c openssl_x_diffie_hellman.h \
        openssl_ed_private_key.c openssl_ed_private_key.h \
-       openssl_ed_public_key.c openssl_ed_public_key.h
+       openssl_ed_public_key.c openssl_ed_public_key.h \
+       openssl_xof.c openssl_xof.h
 
 libstrongswan_openssl_la_LDFLAGS = -module -avoid-version
 libstrongswan_openssl_la_LIBADD  = $(OPENSSL_LIB)
index 73e3245..e17bb32 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2018 Tobias Brunner
+ * Copyright (C) 2008-2020 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
  * HSR Hochschule fuer Technik Rapperswil
  *
@@ -50,6 +50,7 @@
 #include "openssl_x_diffie_hellman.h"
 #include "openssl_ed_public_key.h"
 #include "openssl_ed_private_key.h"
+#include "openssl_xof.h"
 
 #ifndef FIPS_MODE
 #define FIPS_MODE 0
@@ -546,7 +547,7 @@ METHOD(plugin_t, get_features, int,
                        PLUGIN_PROVIDE(HASHER, HASH_SHA384),
                        PLUGIN_PROVIDE(HASHER, HASH_SHA512),
 #endif
-/* SHA3 was added with OpenSSL 1.1.1, it doesn't seem to be possible to
+/* SHA3/SHAKE was added with OpenSSL 1.1.1, it doesn't seem to be possible to
  * disable it, defining the checked var prevents registration, though */
 #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_SHA3)
                        PLUGIN_PROVIDE(HASHER, HASH_SHA3_224),
@@ -554,6 +555,11 @@ METHOD(plugin_t, get_features, int,
                        PLUGIN_PROVIDE(HASHER, HASH_SHA3_384),
                        PLUGIN_PROVIDE(HASHER, HASH_SHA3_512),
 #endif
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_SHAKE)
+               PLUGIN_REGISTER(XOF, openssl_xof_create),
+                       PLUGIN_PROVIDE(XOF, XOF_SHAKE_128),
+                       PLUGIN_PROVIDE(XOF, XOF_SHAKE_256),
+#endif
 #ifndef OPENSSL_NO_SHA1
                /* keyed sha1 hasher (aka prf) */
                PLUGIN_REGISTER(PRF, openssl_sha1_prf_create),
diff --git a/src/libstrongswan/plugins/openssl/openssl_xof.c b/src/libstrongswan/plugins/openssl/openssl_xof.c
new file mode 100644 (file)
index 0000000..564100a
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2020 Tobias Brunner
+ * 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 <openssl/evp.h>
+
+/* SHA3 was added with 1.1.1 */
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_SHAKE)
+
+#include "openssl_xof.h"
+
+#define KECCAK_STATE_SIZE 200 /* 1600 bits*/
+
+typedef struct private_xof_t private_xof_t;
+
+/**
+ * Private data
+ */
+struct private_xof_t {
+
+       /**
+        * Public interface.
+        */
+       xof_t public;
+
+       /**
+        * XOF algorithm to be used
+        */
+       ext_out_function_t algorithm;
+
+       /**
+        * Internal type reference
+        */
+       const EVP_MD *md;
+
+       /**
+        * Internal context
+        */
+       EVP_MD_CTX *ctx;
+};
+
+METHOD(xof_t, get_type, ext_out_function_t,
+       private_xof_t *this)
+{
+       return this->algorithm;
+}
+
+METHOD(xof_t, get_bytes, bool,
+       private_xof_t *this, size_t out_len, uint8_t *buffer)
+{
+       return EVP_DigestFinalXOF(this->ctx, buffer, out_len) == 1;
+}
+
+METHOD(xof_t, allocate_bytes, bool,
+       private_xof_t *this, size_t out_len, chunk_t *chunk)
+{
+       *chunk = chunk_alloc(out_len);
+       return EVP_DigestFinalXOF(this->ctx, chunk->ptr, out_len) == 1;
+}
+
+METHOD(xof_t, get_block_size, size_t,
+       private_xof_t *this)
+{
+       return EVP_MD_block_size(this->md);
+}
+
+METHOD(xof_t, get_seed_size, size_t,
+       private_xof_t *this)
+{
+       return KECCAK_STATE_SIZE - EVP_MD_block_size(this->md);
+}
+
+METHOD(xof_t, set_seed, bool,
+       private_xof_t *this, chunk_t seed)
+{
+       return EVP_DigestInit_ex(this->ctx, this->md, NULL) == 1 &&
+                  EVP_DigestUpdate(this->ctx, seed.ptr, seed.len) == 1;
+}
+
+METHOD(xof_t, destroy, void,
+       private_xof_t *this)
+{
+       EVP_MD_CTX_free(this->ctx);
+       free(this);
+}
+
+/*
+ * Described in header
+ */
+xof_t *openssl_xof_create(ext_out_function_t algorithm)
+{
+       private_xof_t *this;
+       const EVP_MD *md;
+
+       switch (algorithm)
+       {
+               case XOF_SHAKE_128:
+                       md = EVP_shake128();
+                       break;
+               case XOF_SHAKE_256:
+                       md = EVP_shake256();
+                       break;
+               default:
+                       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,
+               },
+               .algorithm = algorithm,
+               .md = md,
+               .ctx = EVP_MD_CTX_new(),
+       );
+       return &this->public;
+}
+
+#endif /* OPENSSL_NO_ECDH */
diff --git a/src/libstrongswan/plugins/openssl/openssl_xof.h b/src/libstrongswan/plugins/openssl/openssl_xof.h
new file mode 100644 (file)
index 0000000..8b3411a
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 Tobias Brunner
+ * 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.
+ */
+
+/**
+ * Implementation of the SHAKE128/256 XOF algorithm using OpenSSL.
+ *
+ * @defgroup openssl_xof openssl_xof
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_XOF_H_
+#define OPENSSL_XOF_H_
+
+#include <library.h>
+
+/**
+ * Creates a new xof_t object.
+ *
+ * @param algorithm            XOF algorithm to create
+ * @return                             object, NULL if not supported
+ */
+xof_t *openssl_xof_create(ext_out_function_t algorithm);
+
+#endif /** OPENSSL_XOF_H_ @}*/