Mercurial > dropbear
changeset 1589:35af85194268
Add kexdh and kexecdh fuzzers
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 05 Mar 2018 11:50:31 +0800 |
parents | 149a5329d83a |
children | 68d5d8e84a92 |
files | Makefile.in fuzz-common.c fuzz-harness.c fuzz.h fuzzer-kexdh.c fuzzer-kexecdh.c |
diffstat | 6 files changed, 168 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.in Mon Mar 05 00:59:17 2018 +0800 +++ b/Makefile.in Mon Mar 05 11:50:31 2018 +0800 @@ -255,7 +255,7 @@ ## Fuzzing targets # list of fuzz targets -FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths +FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths fuzzer-kexdh fuzzer-kexecdh FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS)) @@ -280,13 +280,18 @@ fuzzer-preauth_nomaths: fuzzer-preauth_nomaths.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ - fuzzer-pubkey: fuzzer-pubkey.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ fuzzer-verify: fuzzer-verify.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ +fuzzer-kexdh: fuzzer-kexdh.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) + $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ + +fuzzer-kexecdh: fuzzer-kexecdh.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) + $(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ + fuzzer-%.options: Makefile echo "[libfuzzer]" > $@ echo "max_len = 50000" >> $@
--- a/fuzz-common.c Mon Mar 05 00:59:17 2018 +0800 +++ b/fuzz-common.c Mon Mar 05 11:50:31 2018 +0800 @@ -22,6 +22,7 @@ fuzz.input = m_malloc(sizeof(buffer)); _dropbear_log = fuzz_dropbear_log; crypto_init(); + fuzz_seed(); /* let any messages get flushed */ setlinebuf(stdout); } @@ -188,3 +189,13 @@ return 0; } + +const void* fuzz_get_algo(const algo_type *algos, const char* name) { + const algo_type *t; + for (t = algos; t->name; t++) { + if (strcmp(t->name, name) == 0) { + return t->data; + } + } + assert(0); +}
--- a/fuzz-harness.c Mon Mar 05 00:59:17 2018 +0800 +++ b/fuzz-harness.c Mon Mar 05 11:50:31 2018 +0800 @@ -9,6 +9,7 @@ buffer *input = buf_new(100000); for (i = 1; i < argc; i++) { + printf("arg %s\n", argv[i]); #if DEBUG_TRACE if (strcmp(argv[i], "-v") == 0) { debug_trace = 1;
--- a/fuzz.h Mon Mar 05 00:59:17 2018 +0800 +++ b/fuzz.h Mon Mar 05 11:50:31 2018 +0800 @@ -19,6 +19,7 @@ int fuzz_set_input(const uint8_t *Data, size_t Size); int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths); +const void* fuzz_get_algo(const algo_type *algos, const char* name); // fuzzer functions that intrude into general code void fuzz_kex_fakealgos(void);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fuzzer-kexdh.c Mon Mar 05 11:50:31 2018 +0800 @@ -0,0 +1,70 @@ +#include "fuzz.h" +#include "session.h" +#include "fuzz-wrapfd.h" +#include "debug.h" +#include "runopts.h" +#include "algo.h" +#include "bignum.h" + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + static int once = 0; + static struct key_context* keep_newkeys = NULL; + #define NUM_PARAMS 800 + static struct kex_dh_param *dh_params[NUM_PARAMS]; + + if (!once) { + 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, "diffie-hellman-group14-sha256"); + keep_newkeys->algo_hostkey = DROPBEAR_SIGNKEY_ECDSA_NISTP256; + ses.newkeys = keep_newkeys; + + /* Pre-generate parameters */ + int i; + for (i = 0; i < NUM_PARAMS; i++) { + dh_params[i] = gen_kexdh_param(); + } + + once = 1; + } + + if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) { + return 0; + } + + m_malloc_set_epoch(1); + + if (setjmp(fuzz.jmp) == 0) { + /* Based on recv_msg_kexdh_init()/send_msg_kexdh_reply() + with DROPBEAR_KEX_NORMAL_DH */ + ses.newkeys = keep_newkeys; + + /* Choose from the collection of ecdh params */ + unsigned int e = buf_getint(fuzz.input); + struct kex_dh_param * dh_param = dh_params[e % NUM_PARAMS]; + + DEF_MP_INT(dh_e); + m_mp_init(&dh_e); + if (buf_getmpint(fuzz.input, &dh_e) != DROPBEAR_SUCCESS) { + dropbear_exit("Bad kex value"); + } + + ses.kexhashbuf = buf_new(4); + buf_putint(ses.kexhashbuf, 12345); + kexdh_comb_key(dh_param, &dh_e, svr_opts.hostkey); + + /* kexhashbuf is freed in kexdh_comb_key */ + m_free(ses.dh_K); + mp_clear(&dh_e); + + m_malloc_free_epoch(1, 0); + } else { + m_malloc_free_epoch(1, 1); + TRACE(("dropbear_exit longjmped")) + /* dropbear_exit jumped here */ + } + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fuzzer-kexecdh.c Mon Mar 05 11:50:31 2018 +0800 @@ -0,0 +1,78 @@ +#include "fuzz.h" +#include "session.h" +#include "fuzz-wrapfd.h" +#include "debug.h" +#include "runopts.h" +#include "algo.h" +#include "bignum.h" + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + static int once = 0; + static const struct dropbear_kex *ecdh[3]; /* 256, 384, 521 */ + static struct key_context* keep_newkeys = NULL; + #define NUM_PARAMS 800 + static struct kex_ecdh_param *ecdh_params[NUM_PARAMS]; + + if (!once) { + fuzz_common_setup(); + fuzz_svr_setup(); + + /* ses gets zeroed by fuzz_set_input */ + keep_newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); + ecdh[0] = fuzz_get_algo(sshkex, "ecdh-sha2-nistp256"); + ecdh[1] = fuzz_get_algo(sshkex, "ecdh-sha2-nistp384"); + ecdh[2] = fuzz_get_algo(sshkex, "ecdh-sha2-nistp521"); + assert(ecdh[0]); + assert(ecdh[1]); + assert(ecdh[2]); + keep_newkeys->algo_hostkey = DROPBEAR_SIGNKEY_ECDSA_NISTP256; + ses.newkeys = keep_newkeys; + + /* Pre-generate parameters */ + int i; + for (i = 0; i < NUM_PARAMS; i++) { + ses.newkeys->algo_kex = ecdh[i % 3]; + ecdh_params[i] = gen_kexecdh_param(); + } + + once = 1; + } + + if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) { + return 0; + } + + m_malloc_set_epoch(1); + + if (setjmp(fuzz.jmp) == 0) { + /* Based on recv_msg_kexdh_init()/send_msg_kexdh_reply() + with DROPBEAR_KEX_ECDH */ + ses.newkeys = keep_newkeys; + + /* random choice of ecdh 256, 384, 521 */ + unsigned char b = buf_getbyte(fuzz.input); + ses.newkeys->algo_kex = ecdh[b % 3]; + + /* Choose from the collection of ecdh params */ + unsigned int e = buf_getint(fuzz.input); + struct kex_ecdh_param *ecdh_param = ecdh_params[e % NUM_PARAMS]; + + buffer * ecdh_qs = buf_getstringbuf(fuzz.input); + + ses.kexhashbuf = buf_new(4); + buf_putint(ses.kexhashbuf, 12345); + kexecdh_comb_key(ecdh_param, ecdh_qs, svr_opts.hostkey); + + /* kexhashbuf is freed in kexdh_comb_key */ + m_free(ses.dh_K); + buf_free(ecdh_qs); + + m_malloc_free_epoch(1, 0); + } else { + m_malloc_free_epoch(1, 1); + TRACE(("dropbear_exit longjmped")) + /* dropbear_exit jumped here */ + } + + return 0; +}