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..7753034a --- /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 * q_s = buf_getstringbuf(fuzz.input); + + ses.kexhashbuf = buf_new(KEXHASHBUF_MAX_INTS); + kexpqhybrid_comb_key(param, q_s, hostkey); + + free_kexpqhybrid_param(param); + + buf_free(ses.dh_K_bytes); + buf_free(q_s); + + 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..b023fef2 --- /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 * q_c = buf_getstringbuf(fuzz.input); + + ses.kexhashbuf = buf_new(KEXHASHBUF_MAX_INTS); + kexpqhybrid_comb_key(param, q_c, svr_opts.hostkey); + + free_kexpqhybrid_param(param); + + buf_free(ses.dh_K_bytes); + buf_free(q_c); + + 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; +}