/src/dropbear/fuzz/fuzzer-kexecdh.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "fuzz.h" |
2 | | #include "session.h" |
3 | | #include "fuzz-wrapfd.h" |
4 | | #include "debug.h" |
5 | | #include "runopts.h" |
6 | | #include "algo.h" |
7 | | #include "bignum.h" |
8 | | |
9 | | static const struct dropbear_kex *ecdh[3]; /* 256, 384, 521 */ |
10 | | static struct key_context* keep_newkeys = NULL; |
11 | | /* number of generated parameters. An arbitrary limit, but will delay startup */ |
12 | 952 | #define NUM_PARAMS 80 |
13 | | static struct kex_ecdh_param *ecdh_params[NUM_PARAMS]; |
14 | | |
15 | | static void setup() __attribute__((constructor)); |
16 | | // Perform initial setup here to avoid hitting timeouts on first run |
17 | 2 | static void setup() { |
18 | 2 | fuzz_common_setup(); |
19 | 2 | fuzz_svr_setup(); |
20 | | |
21 | | /* ses gets zeroed by fuzz_set_input */ |
22 | 2 | keep_newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); |
23 | 2 | ecdh[0] = fuzz_get_algo(sshkex, "ecdh-sha2-nistp256"); |
24 | 2 | ecdh[1] = fuzz_get_algo(sshkex, "ecdh-sha2-nistp384"); |
25 | 2 | ecdh[2] = fuzz_get_algo(sshkex, "ecdh-sha2-nistp521"); |
26 | 2 | assert(ecdh[0]); |
27 | 2 | assert(ecdh[1]); |
28 | 2 | assert(ecdh[2]); |
29 | 2 | keep_newkeys->algo_hostkey = DROPBEAR_SIGNKEY_ECDSA_NISTP256; |
30 | 2 | ses.newkeys = keep_newkeys; |
31 | | |
32 | | /* Pre-generate parameters */ |
33 | 2 | int i; |
34 | 162 | for (i = 0; i < NUM_PARAMS; i++) { |
35 | 160 | ses.newkeys->algo_kex = ecdh[i % 3]; |
36 | 160 | ecdh_params[i] = gen_kexecdh_param(); |
37 | 160 | } |
38 | 2 | } |
39 | | |
40 | 790 | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { |
41 | | |
42 | 790 | if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) { |
43 | 0 | return 0; |
44 | 0 | } |
45 | | |
46 | 790 | m_malloc_set_epoch(1); |
47 | | |
48 | 790 | if (setjmp(fuzz.jmp) == 0) { |
49 | | /* Based on recv_msg_kexdh_init()/send_msg_kexdh_reply() |
50 | | with DROPBEAR_KEX_ECDH */ |
51 | 790 | ses.newkeys = keep_newkeys; |
52 | | |
53 | | /* random choice of ecdh 256, 384, 521 */ |
54 | 790 | unsigned char b = buf_getbyte(fuzz.input); |
55 | 790 | ses.newkeys->algo_kex = ecdh[b % 3]; |
56 | | |
57 | | /* Choose from the collection of ecdh params */ |
58 | 790 | unsigned int e = buf_getint(fuzz.input); |
59 | 790 | struct kex_ecdh_param *ecdh_param = ecdh_params[e % NUM_PARAMS]; |
60 | | |
61 | 790 | buffer * ecdh_qc = buf_getstringbuf(fuzz.input); |
62 | | |
63 | 790 | ses.kexhashbuf = buf_new(KEXHASHBUF_MAX_INTS); |
64 | 790 | kexecdh_comb_key(ecdh_param, ecdh_qc, svr_opts.hostkey); |
65 | | |
66 | 790 | mp_clear(ses.dh_K); |
67 | 790 | m_free(ses.dh_K); |
68 | 790 | buf_free(ecdh_qc); |
69 | | |
70 | 790 | buf_free(ses.hash); |
71 | 790 | buf_free(ses.session_id); |
72 | | /* kexhashbuf is freed in kexdh_comb_key */ |
73 | | |
74 | 790 | m_malloc_free_epoch(1, 0); |
75 | 790 | } else { |
76 | 0 | m_malloc_free_epoch(1, 1); |
77 | 0 | TRACE(("dropbear_exit longjmped")) |
78 | | /* dropbear_exit jumped here */ |
79 | 0 | } |
80 | | |
81 | 790 | return 0; |
82 | 790 | } |