Commit 444a1dc0e3 for strongswan.org

commit 444a1dc0e3594cbd81a5cc93bef77f367b56151a
Author: Tobias Brunner <tobias@strongswan.org>
Date:   Wed Feb 11 11:14:53 2026 +0100

    fuzz: Create fuzzers with default and custom crypto plugins

    The pa_tnc fuzzer does not rely on any plugins and the pb_tnc fuzzer is
    a bit special in that it does use code from the tnccs-20 plugin, but that
    doesn't actually have to be loaded as such. The fuzzer directly calls
    statically linked code from the plugin.

diff --git a/configure.ac b/configure.ac
index 9b0546e82e..8525c2c8e2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1419,6 +1419,9 @@ if test x$asan = xtrue; then
 	if test x$botan = xtrue; then
 		LDFLAGS="$LDFLAGS -lstdc++"
 	fi
+fi
+
+if test x$asan = xtrue -o x$fuzzing = xtrue; then
 	if test x$openssl = xtrue; then
 		# we need to suppress some leaks with OpenSSL 3 as we don't deinitialze
 		# it properly
@@ -1525,12 +1528,14 @@ pool_plugins=
 attest_plugins=
 pki_plugins=
 scripts_plugins=
-fuzz_plugins=
 manager_plugins=
 medsrv_plugins=
 nm_plugins=
 cmd_plugins=
 aikgen_plugins=
+# plugin lists for fuzzing, one with the default, the other with the custom plugins
+fd_plugins=
+fc_plugins=

 # location specific lists for checksumming,
 # for src/libcharon, src/libstrongswan, src/libtnccs and src/libtpmtss
@@ -1549,21 +1554,21 @@ ADD_PLUGIN([aes],                  [s charon swanctl pki scripts nm cmd])
 ADD_PLUGIN([des],                  [s charon swanctl pki scripts nm cmd])
 ADD_PLUGIN([blowfish],             [s charon swanctl pki scripts nm cmd])
 ADD_PLUGIN([rc2],                  [s charon swanctl pki scripts nm cmd])
-ADD_PLUGIN([sha2],                 [s charon swanctl pki scripts medsrv attest nm cmd aikgen fuzz])
-ADD_PLUGIN([sha3],                 [s charon swanctl pki scripts medsrv attest nm cmd aikgen fuzz])
-ADD_PLUGIN([sha1],                 [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen fuzz])
+ADD_PLUGIN([sha2],                 [s charon swanctl pki scripts medsrv attest nm cmd aikgen fc])
+ADD_PLUGIN([sha3],                 [s charon swanctl pki scripts medsrv attest nm cmd aikgen fc])
+ADD_PLUGIN([sha1],                 [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen fc])
 ADD_PLUGIN([md4],                  [s charon swanctl pki nm cmd])
 ADD_PLUGIN([md5],                  [s charon swanctl pki scripts attest nm cmd aikgen])
-ADD_PLUGIN([mgf1],                 [s charon swanctl pki scripts medsrv attest nm cmd aikgen])
+ADD_PLUGIN([mgf1],                 [s charon swanctl pki scripts medsrv attest nm cmd aikgen fc])
 ADD_PLUGIN([rdrand],               [s charon swanctl pki scripts medsrv attest nm cmd aikgen])
 ADD_PLUGIN([random],               [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen])
 ADD_PLUGIN([nonce],                [s charon nm cmd aikgen])
-ADD_PLUGIN([x509],                 [s charon swanctl pki scripts attest nm cmd aikgen fuzz])
+ADD_PLUGIN([x509],                 [s charon swanctl pki scripts attest nm cmd aikgen fd fc])
 ADD_PLUGIN([revocation],           [s charon pki nm cmd])
 ADD_PLUGIN([constraints],          [s charon pki nm cmd])
 ADD_PLUGIN([acert],                [s charon])
 ADD_PLUGIN([pubkey],               [s charon swanctl pki cmd aikgen])
-ADD_PLUGIN([pkcs1],                [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen fuzz])
+ADD_PLUGIN([pkcs1],                [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen fd fc])
 ADD_PLUGIN([pkcs7],                [s charon swanctl pki scripts nm cmd])
 ADD_PLUGIN([pkcs12],               [s charon swanctl pki scripts cmd])
 ADD_PLUGIN([pgp],                  [s charon])
@@ -1571,16 +1576,16 @@ ADD_PLUGIN([dnskey],               [s charon swanctl pki])
 ADD_PLUGIN([sshkey],               [s charon swanctl pki nm cmd])
 ADD_PLUGIN([dnscert],              [c charon])
 ADD_PLUGIN([ipseckey],             [c charon])
-ADD_PLUGIN([pem],                  [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen fuzz])
+ADD_PLUGIN([pem],                  [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen fd fc])
 ADD_PLUGIN([padlock],              [s charon])
-ADD_PLUGIN([openssl],              [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen])
+ADD_PLUGIN([openssl],              [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen fd])
 ADD_PLUGIN([wolfssl],              [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen])
 ADD_PLUGIN([gcrypt],               [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen])
 ADD_PLUGIN([botan],                [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen])
 ADD_PLUGIN([pkcs8],                [s charon swanctl pki scripts manager medsrv attest nm cmd])
 ADD_PLUGIN([af-alg],               [s charon swanctl pki scripts medsrv attest nm cmd aikgen])
 ADD_PLUGIN([fips-prf],             [s charon nm cmd])
-ADD_PLUGIN([gmp],                  [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen fuzz])
+ADD_PLUGIN([gmp],                  [s charon swanctl pki scripts manager medsrv attest nm cmd aikgen fc])
 ADD_PLUGIN([curve25519],           [s charon swanctl pki scripts nm cmd])
 ADD_PLUGIN([agent],                [s charon nm cmd])
 ADD_PLUGIN([keychain],             [s charon cmd])
@@ -1684,12 +1689,13 @@ AC_SUBST(pool_plugins)
 AC_SUBST(attest_plugins)
 AC_SUBST(pki_plugins)
 AC_SUBST(scripts_plugins)
-AC_SUBST(fuzz_plugins)
 AC_SUBST(manager_plugins)
 AC_SUBST(medsrv_plugins)
 AC_SUBST(nm_plugins)
 AC_SUBST(cmd_plugins)
 AC_SUBST(aikgen_plugins)
+AC_SUBST(fd_plugins)
+AC_SUBST(fc_plugins)

 AC_SUBST(c_plugins)
 AC_SUBST(p_plugins)
diff --git a/fuzz/.gitignore b/fuzz/.gitignore
index b8da0a0c94..ec40917496 100644
--- a/fuzz/.gitignore
+++ b/fuzz/.gitignore
@@ -1,8 +1,12 @@
-fuzz_certs
-fuzz_crls
+fuzz_certs_cus
+fuzz_certs_def
+fuzz_crls_cus
+fuzz_crls_def
 fuzz_ids
 fuzz_ike
-fuzz_ocsp_req
-fuzz_ocsp_rsp
+fuzz_ocsp_req_cus
+fuzz_ocsp_req_def
+fuzz_ocsp_rsp_cus
+fuzz_ocsp_rsp_def
 fuzz_pa_tnc
 fuzz_pb_tnc
diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am
index c357340157..c44539b76c 100644
--- a/fuzz/Makefile.am
+++ b/fuzz/Makefile.am
@@ -8,14 +8,26 @@ AM_CPPFLAGS = @CPPFLAGS@ \
 	-I$(top_srcdir)/src/libtnccs \
 	-I$(top_srcdir)/src/libtnccs/plugins/tnccs_20 \
 	-I$(top_srcdir)/src/libradius \
-	-DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\"" \
-	-DPLUGINS="\"${fuzz_plugins}\""
+	-DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\""
+
+fuzz_cppflags_def = ${AM_CPPFLAGS} \
+	-DPLUGINS="\"${fd_plugins}\""
+
+fuzz_cppflags_cus = ${AM_CPPFLAGS} \
+	-DPLUGINS="\"${fc_plugins}\""

 fuzz_ldflags = ${libfuzzer} \
 	$(top_builddir)/src/libstrongswan/.libs/libstrongswan.a \
-	-Wl,-Bstatic -lcrypto -Wl,-Bdynamic \
 	@FUZZING_LDFLAGS@

+if USE_OPENSSL
+fuzz_ldflags += -Wl,-Bstatic -lcrypto -Wl,-Bdynamic
+endif
+
+if USE_GMP
+fuzz_ldflags += -Wl,-Bstatic -lgmp -Wl,-Bdynamic
+endif
+
 pa_tnc_ldflags = \
 	$(top_builddir)/src/libimcv/.libs/libimcv.a \
 	$(top_builddir)/src/libtncif/.libs/libtncif.a \
@@ -32,27 +44,45 @@ ike_ldflags = \
 	$(top_builddir)/src/libradius/.libs/libradius.a \
 	$(fuzz_ldflags)

-FUZZ_TARGETS=fuzz_certs fuzz_crls fuzz_ocsp_req fuzz_ocsp_rsp \
-	fuzz_ids fuzz_pa_tnc fuzz_pb_tnc fuzz_ike
+# fuzzers that use crypto plugins in a significant way
+fuzzers_with_plugins = \
+	fuzz_certs fuzz_crls fuzz_ocsp_req fuzz_ocsp_rsp

-all-local: $(FUZZ_TARGETS)
+fuzzers_with_def = $(fuzzers_with_plugins:%=%_def)
+fuzzers_with_cus = $(fuzzers_with_plugins:%=%_cus)

-CLEANFILES=$(FUZZ_TARGETS)
+fuzzers_no_plugins = \
+	fuzz_ids fuzz_ike fuzz_pa_tnc fuzz_pb_tnc

-fuzz_certs: fuzz_certs.c ${libfuzzer}
-	$(CC) $(AM_CPPFLAGS) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+ALL_FUZZERS=$(fuzzers_with_def) $(fuzzers_with_cus) $(fuzzers_no_plugins)

-fuzz_crls: fuzz_crls.c ${libfuzzer}
-	$(CC) $(AM_CPPFLAGS) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+all-local: $(ALL_FUZZERS)

-fuzz_ocsp_req: fuzz_ocsp_req.c ${libfuzzer}
-	$(CC) $(AM_CPPFLAGS) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+CLEANFILES=$(ALL_FUZZERS)

-fuzz_ocsp_rsp: fuzz_ocsp_rsp.c ${libfuzzer}
-	$(CC) $(AM_CPPFLAGS) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+fuzz_certs_def: fuzz_certs.c ${libfuzzer}
+	$(CC) $(fuzz_cppflags_def) $(CFLAGS) -o $@ $< $(fuzz_ldflags)

-fuzz_ids: fuzz_ids.c ${libfuzzer}
-	$(CC) $(AM_CPPFLAGS) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+fuzz_certs_cus: fuzz_certs.c ${libfuzzer}
+	$(CC) $(fuzz_cppflags_cus) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+
+fuzz_crls_def: fuzz_crls.c ${libfuzzer}
+	$(CC) $(fuzz_cppflags_def) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+
+fuzz_crls_cus: fuzz_crls.c ${libfuzzer}
+	$(CC) $(fuzz_cppflags_cus) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+
+fuzz_ocsp_req_def: fuzz_ocsp_req.c ${libfuzzer}
+	$(CC) $(fuzz_cppflags_def) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+
+fuzz_ocsp_req_cus: fuzz_ocsp_req.c ${libfuzzer}
+	$(CC) $(fuzz_cppflags_cus) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+
+fuzz_ocsp_rsp_def: fuzz_ocsp_rsp.c ${libfuzzer}
+	$(CC) $(fuzz_cppflags_def) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+
+fuzz_ocsp_rsp_cus: fuzz_ocsp_rsp.c ${libfuzzer}
+	$(CC) $(fuzz_cppflags_cus) $(CFLAGS) -o $@ $< $(fuzz_ldflags)

 fuzz_pa_tnc: fuzz_pa_tnc.c ${libfuzzer}
 	$(CC) $(AM_CPPFLAGS) $(CFLAGS) -o $@ $< $(pa_tnc_ldflags)
@@ -60,6 +90,9 @@ fuzz_pa_tnc: fuzz_pa_tnc.c ${libfuzzer}
 fuzz_pb_tnc: fuzz_pb_tnc.c ${libfuzzer}
 	$(CC) $(AM_CPPFLAGS) $(CFLAGS) -o $@ $< $(pb_tnc_ldflags)

+fuzz_ids: fuzz_ids.c ${libfuzzer}
+	$(CC) $(AM_CPPFLAGS) $(CFLAGS) -o $@ $< $(fuzz_ldflags)
+
 fuzz_ike: fuzz_ike.c ${libfuzzer}
 	$(CC) $(AM_CPPFLAGS) $(CFLAGS) -o $@ $< $(ike_ldflags)

@@ -68,8 +101,11 @@ libFuzzerLocal_a_SOURCES = libFuzzerLocal.c
 libFuzzerLocal_a_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la

 check: all
-	for f in $(FUZZ_TARGETS); do \
+	$(TESTS_ENVIRONMENT) \
+	for f in $(ALL_FUZZERS); do \
 		corpus=$${f#fuzz_}; \
+		corpus=$${corpus%_def}; \
+		corpus=$${corpus%_cus}; \
 		initial=$(FUZZING_CORPORA)/$${corpus}; \
 		crashes=$${initial}-crash; \
 		test ! -d $${initial} || ./$$f $${initial}/* || exit 1; \
diff --git a/fuzz/fuzz_pa_tnc.c b/fuzz/fuzz_pa_tnc.c
index 79ecb3664d..8271d43be0 100644
--- a/fuzz/fuzz_pa_tnc.c
+++ b/fuzz/fuzz_pa_tnc.c
@@ -31,12 +31,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)

 	dbg_default_set_level(-1);
 	library_init(NULL, "fuzz_pa_tnc");
-	plugin_loader_add_plugindirs(PLUGINDIR, PLUGINS);
-	if (!lib->plugins->load(lib->plugins, PLUGINS))
-	{
-		return 1;
-	}
 	libimcv_init(FALSE);
+
 	chunk = chunk_create((u_char*)buf, len);

 	/* Parse incoming PA-TNC message */
@@ -68,7 +64,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 	msg->destroy(msg);

 	libimcv_deinit();
-	lib->plugins->unload(lib->plugins);
 	library_deinit();
 	return 0;
 }
diff --git a/fuzz/fuzz_pb_tnc.c b/fuzz/fuzz_pb_tnc.c
index 4a6c1e6001..a1636fcd99 100644
--- a/fuzz/fuzz_pb_tnc.c
+++ b/fuzz/fuzz_pb_tnc.c
@@ -20,7 +20,6 @@
 #include <state_machine/pb_tnc_state_machine.h>
 #include <utils/debug.h>

-
 int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 {
 	pb_tnc_batch_t *batch;
@@ -33,11 +32,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)

 	dbg_default_set_level(-1);
 	library_init(NULL, "fuzz_pb_tnc");
-	plugin_loader_add_plugindirs(PLUGINDIR, PLUGINS);
-	if (!lib->plugins->load(lib->plugins, PLUGINS))
-	{
-		return 1;
-	}
+
 	chunk = chunk_create((u_char*)buf, len);

 	INIT(state,
@@ -73,7 +68,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 	batch->destroy(batch);

 	free(state);
-	lib->plugins->unload(lib->plugins);
 	library_deinit();
 	return 0;
 }
diff --git a/scripts/test.sh b/scripts/test.sh
index 14e7770340..111ed1c9c2 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -433,6 +433,8 @@ fuzzing)
 	CFLAGS="$CFLAGS -DNO_CHECK_MEMWIPE"
 	CONFIG="--enable-fuzzing --enable-static --disable-shared --disable-scripts
 			--enable-imc-test --enable-tnccs-20 --enable-eap-radius"
+	# enable the custom crypto plugins
+	CONFIG="$CONFIG --enable-sha1 --enable-sha2 --enable-sha3 --enable-mgf1 --enable-gmp"
 	# don't run any of the unit tests
 	export TESTS_RUNNERS=
 	# prepare corpora