From dfd29588ce4fc0e0c2955ae229552604595b3277 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Sat, 14 Dec 2024 21:39:08 +0800 Subject: [PATCH] Add fuzzers for sntrup Use separate fuzzers for client vs server since KEMs have an asymmetric API. --- Makefile.in | 3 +- fuzz/fuzzer-kexsntrup-cli.c | 55 +++++++++++++++++++++++++++++++++++++ fuzz/fuzzer-kexsntrup-srv.c | 54 ++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 fuzz/fuzzer-kexsntrup-cli.c create mode 100644 fuzz/fuzzer-kexsntrup-srv.c diff --git a/Makefile.in b/Makefile.in index 979a763b..62bfe0bf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -297,7 +297,8 @@ check: lint # list of fuzz targets FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths \ fuzzer-kexdh fuzzer-kexecdh fuzzer-kexcurve25519 fuzzer-client fuzzer-client_nomaths \ - fuzzer-postauth_nomaths fuzzer-cliconf + fuzzer-postauth_nomaths fuzzer-cliconf \ + fuzzer-kexsntrup-srv fuzzer-kexsntrup-cli FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS)) FUZZ_OBJS = $(addprefix fuzz/,$(addsuffix .o,$(FUZZ_TARGETS))) \ diff --git a/fuzz/fuzzer-kexsntrup-cli.c b/fuzz/fuzzer-kexsntrup-cli.c new file mode 100644 index 00000000..971fa4b7 --- /dev/null +++ b/fuzz/fuzzer-kexsntrup-cli.c @@ -0,0 +1,55 @@ +#include "fuzz.h" +#include "session.h" +#include "fuzz-wrapfd.h" +#include "debug.h" +#include "runopts.h" +#include "algo.h" + +static struct key_context* keep_newkeys = NULL; + +static void setup() __attribute__((constructor)); +static void setup() { + fuzz_common_setup(); + fuzz_cli_setup(); + + keep_newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); + keep_newkeys->algo_kex = fuzz_get_algo(sshkex, "sntrup761x25519-sha512"); +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) { + return 0; + } + + m_malloc_set_epoch(1); + + if (setjmp(fuzz.jmp) == 0) { + /* Arbitrary key to write into a buffer */ + sign_key *hostkey = cli_opts.privkeys->first; + ses.newkeys = keep_newkeys; + + struct kex_pqhybrid_param *param = gen_kexpqhybrid_param(); + + buffer * ecdh_qs = buf_getstringbuf(fuzz.input); + + ses.kexhashbuf = buf_new(KEXHASHBUF_MAX_INTS); + kexpqhybrid_comb_key(param, ecdh_qs, hostkey); + + free_kexpqhybrid_param(param); + + buf_free(ses.dh_K_bytes); + buf_free(ecdh_qs); + + buf_free(ses.hash); + buf_free(ses.session_id); + /* kexhashbuf is freed in kexpqhybrid_comb_key */ + + m_malloc_free_epoch(1, 0); + } else { + m_malloc_free_epoch(1, 1); + TRACE(("dropbear_exit longjmped")) + /* dropbear_exit jumped here */ + } + + return 0; +} diff --git a/fuzz/fuzzer-kexsntrup-srv.c b/fuzz/fuzzer-kexsntrup-srv.c new file mode 100644 index 00000000..0e60ea20 --- /dev/null +++ b/fuzz/fuzzer-kexsntrup-srv.c @@ -0,0 +1,54 @@ +#include "fuzz.h" +#include "session.h" +#include "fuzz-wrapfd.h" +#include "debug.h" +#include "runopts.h" +#include "algo.h" + +static struct key_context* keep_newkeys = NULL; + +static void setup() __attribute__((constructor)); +static void setup() { + fuzz_common_setup(); + fuzz_svr_setup(); + + keep_newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); + keep_newkeys->algo_kex = fuzz_get_algo(sshkex, "sntrup761x25519-sha512"); + keep_newkeys->algo_hostkey = DROPBEAR_SIGNKEY_ED25519; +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) { + return 0; + } + + m_malloc_set_epoch(1); + + if (setjmp(fuzz.jmp) == 0) { + ses.newkeys = keep_newkeys; + + struct kex_pqhybrid_param *param = gen_kexpqhybrid_param(); + + buffer * ecdh_qc = buf_getstringbuf(fuzz.input); + + ses.kexhashbuf = buf_new(KEXHASHBUF_MAX_INTS); + kexpqhybrid_comb_key(param, ecdh_qc, svr_opts.hostkey); + + free_kexpqhybrid_param(param); + + buf_free(ses.dh_K_bytes); + buf_free(ecdh_qc); + + buf_free(ses.hash); + buf_free(ses.session_id); + /* kexhashbuf is freed in kexpqhybrid_comb_key */ + + m_malloc_free_epoch(1, 0); + } else { + m_malloc_free_epoch(1, 1); + TRACE(("dropbear_exit longjmped")) + /* dropbear_exit jumped here */ + } + + return 0; +}