From 96c7692661869f382063d9731bde52409b376e87 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 16 Feb 2022 16:42:55 +0100 Subject: [PATCH] wolfssl: Implement prf+ via wolfSSL's HKDF implementation --- src/libstrongswan/plugins/wolfssl/Makefile.am | 1 + .../plugins/wolfssl/wolfssl_kdf.c | 161 ++++++++++++++++++ .../plugins/wolfssl/wolfssl_kdf.h | 45 +++++ .../plugins/wolfssl/wolfssl_plugin.c | 5 + .../hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/strongswan.conf | 2 +- .../hosts/sun/etc/strongswan.conf | 2 +- .../rw-cert/hosts/carol/etc/strongswan.conf | 2 +- .../rw-cert/hosts/moon/etc/strongswan.conf | 2 +- .../rw-ecp256/hosts/carol/etc/strongswan.conf | 2 +- .../rw-ecp256/hosts/moon/etc/strongswan.conf | 2 +- .../hosts/carol/etc/strongswan.conf | 2 +- .../hosts/moon/etc/strongswan.conf | 2 +- 13 files changed, 221 insertions(+), 9 deletions(-) create mode 100644 src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c create mode 100644 src/libstrongswan/plugins/wolfssl/wolfssl_kdf.h diff --git a/src/libstrongswan/plugins/wolfssl/Makefile.am b/src/libstrongswan/plugins/wolfssl/Makefile.am index 350c3a361a..7409bc9cde 100644 --- a/src/libstrongswan/plugins/wolfssl/Makefile.am +++ b/src/libstrongswan/plugins/wolfssl/Makefile.am @@ -24,6 +24,7 @@ libstrongswan_wolfssl_la_SOURCES = \ wolfssl_ed_public_key.h wolfssl_ed_public_key.c \ wolfssl_hasher.h wolfssl_hasher.c \ wolfssl_hmac.h wolfssl_hmac.c \ + wolfssl_kdf.h wolfssl_kdf.c \ wolfssl_rsa_public_key.h wolfssl_rsa_public_key.c \ wolfssl_rsa_private_key.h wolfssl_rsa_private_key.c \ wolfssl_rng.h wolfssl_rng.c \ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c b/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c new file mode 100644 index 0000000000..7a08a35033 --- /dev/null +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2022 Tobias Brunner, codelabs GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "wolfssl_common.h" + +#if !defined(NO_HMAC) && defined(HAVE_HKDF) + +#include + +#define _GNU_SOURCE +#include "wolfssl_kdf.h" +#include "wolfssl_util.h" + +typedef struct private_kdf_t private_kdf_t; + +/** + * Private data. + */ +struct private_kdf_t { + + /** + * Public interface. + */ + kdf_t public; + + /** + * Hash algorithm type. + */ + int type; + + /** + * Key for KDF. + */ + chunk_t key; + + /** + * Salt for KDF. + */ + chunk_t salt; +}; + +METHOD(kdf_t, get_type, key_derivation_function_t, + private_kdf_t *this) +{ + return KDF_PRF_PLUS; +} + +METHOD(kdf_t, get_bytes, bool, + private_kdf_t *this, size_t out_len, uint8_t *buffer) +{ + if (wc_HKDF_Expand(this->type, this->key.ptr, this->key.len, + this->salt.ptr, this->salt.len, buffer, out_len)) + { + return FALSE; + } + return TRUE; +} + +METHOD(kdf_t, allocate_bytes, bool, + private_kdf_t *this, size_t out_len, chunk_t *chunk) +{ + *chunk = chunk_alloc(out_len); + + if (!get_bytes(this, out_len, chunk->ptr)) + { + chunk_free(chunk); + return FALSE; + } + return TRUE; +} + +METHOD(kdf_t, set_param, bool, + private_kdf_t *this, kdf_param_t param, ...) +{ + chunk_t chunk; + + switch (param) + { + case KDF_PARAM_KEY: + VA_ARGS_GET(param, chunk); + chunk_clear(&this->key); + this->key = chunk_clone(chunk); + break; + case KDF_PARAM_SALT: + VA_ARGS_GET(param, chunk); + chunk_clear(&this->salt); + this->salt = chunk_clone(chunk); + break; + } + return TRUE; +} + +METHOD(kdf_t, destroy, void, + private_kdf_t *this) +{ + chunk_clear(&this->salt); + chunk_clear(&this->key); + free(this); +} + +/* + * Described in header + */ +kdf_t *wolfssl_kdf_create(key_derivation_function_t algo, va_list args) +{ + private_kdf_t *this; + pseudo_random_function_t prf_alg; + enum wc_HashType type; + char buf[8]; + + if (algo != KDF_PRF_PLUS) + { + return NULL; + } + + VA_ARGS_VGET(args, prf_alg); + if (!wolfssl_hash2type(hasher_algorithm_from_prf(prf_alg), &type)) + { + return NULL; + } + + INIT(this, + .public = { + .get_type = _get_type, + .get_bytes = _get_bytes, + .allocate_bytes = _allocate_bytes, + .set_param = _set_param, + .destroy = _destroy, + }, + .type = type, + ); + + /* test if we can actually use the algorithm */ + if (!get_bytes(this, sizeof(buf), buf)) + { + destroy(this); + return NULL; + } + return &this->public; +} + +#endif /* !NO_HMAC && HAVE_HKDF */ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.h b/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.h new file mode 100644 index 0000000000..53fc85fe6c --- /dev/null +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_kdf.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 Tobias Brunner, codelabs GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Implements key derivation functions (KDF) using wolfSSL, in particular prf+, + * which is implemented via wolfSSL's HKDF implementation. + * + * @defgroup wolfssl_kdf wolfssl_kdf + * @{ @ingroup wolfssl_p + */ + +#ifndef WOLFSSL_KDF_H_ +#define WOLFSSL_KDF_H_ + +#include + +/** + * Creates a new kdf_t object. + * + * @param algo algorithm to instantiate + * @param args algorithm-specific arguments + * @return kdf_t object, NULL if not supported + */ +kdf_t *wolfssl_kdf_create(key_derivation_function_t algo, va_list args); + +#endif /** WOLFSSL_KDF_H_ @}*/ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c index cea577709b..fdb8d500e5 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c @@ -36,6 +36,7 @@ #include "wolfssl_ed_public_key.h" #include "wolfssl_hasher.h" #include "wolfssl_hmac.h" +#include "wolfssl_kdf.h" #include "wolfssl_rsa_private_key.h" #include "wolfssl_rsa_public_key.h" #include "wolfssl_rng.h" @@ -185,6 +186,10 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256), PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_512), #endif +#ifdef HAVE_HKDF + PLUGIN_REGISTER(KDF, wolfssl_kdf_create), + PLUGIN_PROVIDE(KDF, KDF_PRF_PLUS), +#endif #endif /* NO_HMAC */ #if (!defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AESCCM))) || \ (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) diff --git a/testing/tests/wolfssl/net2net-ed25519/hosts/moon/etc/strongswan.conf b/testing/tests/wolfssl/net2net-ed25519/hosts/moon/etc/strongswan.conf index a7c8bf258c..3c7664b301 100755 --- a/testing/tests/wolfssl/net2net-ed25519/hosts/moon/etc/strongswan.conf +++ b/testing/tests/wolfssl/net2net-ed25519/hosts/moon/etc/strongswan.conf @@ -5,7 +5,7 @@ swanctl { } charon-systemd { - load = random nonce kdf pem wolfssl pkcs1 pkcs8 x509 revocation curl kernel-netlink socket-default updown vici + load = random nonce pem wolfssl pkcs1 pkcs8 x509 revocation curl kernel-netlink socket-default updown vici syslog { daemon { lib = 2 diff --git a/testing/tests/wolfssl/net2net-sha3-rsa-cert/hosts/moon/etc/strongswan.conf b/testing/tests/wolfssl/net2net-sha3-rsa-cert/hosts/moon/etc/strongswan.conf index be92c6bf7a..c18b002fd2 100755 --- a/testing/tests/wolfssl/net2net-sha3-rsa-cert/hosts/moon/etc/strongswan.conf +++ b/testing/tests/wolfssl/net2net-sha3-rsa-cert/hosts/moon/etc/strongswan.conf @@ -5,5 +5,5 @@ swanctl { } charon-systemd { - load = random nonce kdf pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici + load = random nonce pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici } diff --git a/testing/tests/wolfssl/net2net-sha3-rsa-cert/hosts/sun/etc/strongswan.conf b/testing/tests/wolfssl/net2net-sha3-rsa-cert/hosts/sun/etc/strongswan.conf index 74e0250f07..ea977a3916 100755 --- a/testing/tests/wolfssl/net2net-sha3-rsa-cert/hosts/sun/etc/strongswan.conf +++ b/testing/tests/wolfssl/net2net-sha3-rsa-cert/hosts/sun/etc/strongswan.conf @@ -5,5 +5,5 @@ swanctl { } charon-systemd { - load = random nonce kdf pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici + load = random nonce pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici } diff --git a/testing/tests/wolfssl/rw-cert/hosts/carol/etc/strongswan.conf b/testing/tests/wolfssl/rw-cert/hosts/carol/etc/strongswan.conf index 8b2f30b610..eccb2d37ab 100755 --- a/testing/tests/wolfssl/rw-cert/hosts/carol/etc/strongswan.conf +++ b/testing/tests/wolfssl/rw-cert/hosts/carol/etc/strongswan.conf @@ -5,7 +5,7 @@ swanctl { } charon-systemd { - load = nonce kdf pem wolfssl x509 revocation constraints pkcs1 pubkey curl kernel-netlink socket-default updown vici + load = nonce pem wolfssl x509 revocation constraints pkcs1 pubkey curl kernel-netlink socket-default updown vici rsa_pss = yes } diff --git a/testing/tests/wolfssl/rw-cert/hosts/moon/etc/strongswan.conf b/testing/tests/wolfssl/rw-cert/hosts/moon/etc/strongswan.conf index 8436f6a15b..d88319dee6 100755 --- a/testing/tests/wolfssl/rw-cert/hosts/moon/etc/strongswan.conf +++ b/testing/tests/wolfssl/rw-cert/hosts/moon/etc/strongswan.conf @@ -5,7 +5,7 @@ swanctl { } charon-systemd { - load = nonce test-vectors kdf pem wolfssl x509 revocation constraints pkcs1 pubkey curl kernel-netlink socket-default updown vici + load = nonce test-vectors pem wolfssl x509 revocation constraints pkcs1 pubkey curl kernel-netlink socket-default updown vici rsa_pss = yes integrity_test = yes diff --git a/testing/tests/wolfssl/rw-ecp256/hosts/carol/etc/strongswan.conf b/testing/tests/wolfssl/rw-ecp256/hosts/carol/etc/strongswan.conf index 9c133d3d95..72624afbf1 100755 --- a/testing/tests/wolfssl/rw-ecp256/hosts/carol/etc/strongswan.conf +++ b/testing/tests/wolfssl/rw-ecp256/hosts/carol/etc/strongswan.conf @@ -5,7 +5,7 @@ swanctl { } charon-systemd { - load = nonce kdf pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici + load = nonce pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici rsa_pss = yes } diff --git a/testing/tests/wolfssl/rw-ecp256/hosts/moon/etc/strongswan.conf b/testing/tests/wolfssl/rw-ecp256/hosts/moon/etc/strongswan.conf index 3e4a95fec8..87af233ea7 100755 --- a/testing/tests/wolfssl/rw-ecp256/hosts/moon/etc/strongswan.conf +++ b/testing/tests/wolfssl/rw-ecp256/hosts/moon/etc/strongswan.conf @@ -5,7 +5,7 @@ swanctl { } charon-systemd { - load = nonce test-vectors kdf pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici + load = nonce test-vectors pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici rsa_pss = yes } diff --git a/testing/tests/wolfssl/rw-modp3072/hosts/carol/etc/strongswan.conf b/testing/tests/wolfssl/rw-modp3072/hosts/carol/etc/strongswan.conf index 9c133d3d95..72624afbf1 100755 --- a/testing/tests/wolfssl/rw-modp3072/hosts/carol/etc/strongswan.conf +++ b/testing/tests/wolfssl/rw-modp3072/hosts/carol/etc/strongswan.conf @@ -5,7 +5,7 @@ swanctl { } charon-systemd { - load = nonce kdf pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici + load = nonce pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici rsa_pss = yes } diff --git a/testing/tests/wolfssl/rw-modp3072/hosts/moon/etc/strongswan.conf b/testing/tests/wolfssl/rw-modp3072/hosts/moon/etc/strongswan.conf index 3e4a95fec8..87af233ea7 100755 --- a/testing/tests/wolfssl/rw-modp3072/hosts/moon/etc/strongswan.conf +++ b/testing/tests/wolfssl/rw-modp3072/hosts/moon/etc/strongswan.conf @@ -5,7 +5,7 @@ swanctl { } charon-systemd { - load = nonce test-vectors kdf pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici + load = nonce test-vectors pem wolfssl pkcs1 x509 revocation constraints pubkey curl kernel-netlink socket-default updown vici rsa_pss = yes } -- 2.47.2