From 52c4013bb4c812601df54f70ae8edb57ade7ab5c Mon Sep 17 00:00:00 2001 From: Loganaden Velvindron Date: Sat, 22 Feb 2025 16:24:58 +0000 Subject: [PATCH] Add fuzzers for mlkem hybrid. Signed-off-by: Loganaden Velvindron Signed-off-by: Jaykishan Mutkawoa Signed-off-by: Kavish Nadan --- Makefile.in | 3 ++- fuzz/fuzzer-kexmlkem-cli.c | 55 ++++++++++++++++++++++++++++++++++++++ fuzz/fuzzer-kexmlkem-srv.c | 54 +++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 fuzz/fuzzer-kexmlkem-cli.c create mode 100644 fuzz/fuzzer-kexmlkem-srv.c diff --git a/Makefile.in b/Makefile.in index 80264e46..14db0732 100644 --- a/Makefile.in +++ b/Makefile.in @@ -298,7 +298,8 @@ check: lint 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-kexsntrup-srv fuzzer-kexsntrup-cli + fuzzer-kexsntrup-srv fuzzer-kexsntrup-cli \ + fuzzer-kexmlkem-srv fuzzer-kexmlkem-cli FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS)) FUZZ_OBJS = $(addprefix fuzz/,$(addsuffix .o,$(FUZZ_TARGETS))) \ diff --git a/fuzz/fuzzer-kexmlkem-cli.c b/fuzz/fuzzer-kexmlkem-cli.c new file mode 100644 index 00000000..8698ac5f --- /dev/null +++ b/fuzz/fuzzer-kexmlkem-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, "mlkem761x25519-sha256"); +} + +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->item; + 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-kexmlkem-srv.c b/fuzz/fuzzer-kexmlkem-srv.c new file mode 100644 index 00000000..1bdcdfb0 --- /dev/null +++ b/fuzz/fuzzer-kexmlkem-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, "mlkem768x25519-sha256"); + 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; +}