119261079SEd Maste // libfuzzer driver for key exchange fuzzing.
219261079SEd Maste
319261079SEd Maste
419261079SEd Maste #include <sys/types.h>
519261079SEd Maste #include <stdio.h>
619261079SEd Maste #include <stdint.h>
719261079SEd Maste #include <stdlib.h>
819261079SEd Maste #include <string.h>
919261079SEd Maste
1019261079SEd Maste extern "C" {
1119261079SEd Maste
1219261079SEd Maste #include "includes.h"
1319261079SEd Maste #include "ssherr.h"
1419261079SEd Maste #include "ssh_api.h"
1519261079SEd Maste #include "sshbuf.h"
1619261079SEd Maste #include "packet.h"
1719261079SEd Maste #include "myproposal.h"
1819261079SEd Maste #include "xmalloc.h"
1919261079SEd Maste #include "authfile.h"
2019261079SEd Maste #include "log.h"
2119261079SEd Maste
2219261079SEd Maste #include "fixed-keys.h"
2319261079SEd Maste
2419261079SEd Maste // Define if you want to generate traces.
2519261079SEd Maste /* #define STANDALONE 1 */
2619261079SEd Maste
2719261079SEd Maste static int prepare_key(struct shared_state *st, int keytype, int bits);
2819261079SEd Maste
2919261079SEd Maste struct shared_state {
3019261079SEd Maste size_t nkeys;
3119261079SEd Maste struct sshkey **privkeys, **pubkeys;
3219261079SEd Maste };
3319261079SEd Maste
3419261079SEd Maste struct test_state {
3519261079SEd Maste struct sshbuf *smsgs, *cmsgs; /* output, for standalone mode */
3619261079SEd Maste struct sshbuf *sin, *cin; /* input; setup per-test in do_kex_with_key */
3719261079SEd Maste struct sshbuf *s_template, *c_template; /* main copy of input */
3819261079SEd Maste };
3919261079SEd Maste
4019261079SEd Maste static int
do_send_and_receive(struct ssh * from,struct ssh * to,struct sshbuf * store,int clobber,size_t * n)4119261079SEd Maste do_send_and_receive(struct ssh *from, struct ssh *to,
4219261079SEd Maste struct sshbuf *store, int clobber, size_t *n)
4319261079SEd Maste {
4419261079SEd Maste u_char type;
4519261079SEd Maste size_t len;
4619261079SEd Maste const u_char *buf;
4719261079SEd Maste int r;
4819261079SEd Maste
4919261079SEd Maste for (*n = 0;; (*n)++) {
5019261079SEd Maste if ((r = ssh_packet_next(from, &type)) != 0) {
5119261079SEd Maste debug_fr(r, "ssh_packet_next");
5219261079SEd Maste return r;
5319261079SEd Maste }
5419261079SEd Maste if (type != 0)
5519261079SEd Maste return 0;
5619261079SEd Maste buf = ssh_output_ptr(from, &len);
5719261079SEd Maste debug_f("%zu%s", len, clobber ? " ignore" : "");
5819261079SEd Maste if (len == 0)
5919261079SEd Maste return 0;
6019261079SEd Maste if ((r = ssh_output_consume(from, len)) != 0) {
6119261079SEd Maste debug_fr(r, "ssh_output_consume");
6219261079SEd Maste return r;
6319261079SEd Maste }
6419261079SEd Maste if (store != NULL && (r = sshbuf_put(store, buf, len)) != 0) {
6519261079SEd Maste debug_fr(r, "sshbuf_put");
6619261079SEd Maste return r;
6719261079SEd Maste }
6819261079SEd Maste if (!clobber && (r = ssh_input_append(to, buf, len)) != 0) {
6919261079SEd Maste debug_fr(r, "ssh_input_append");
7019261079SEd Maste return r;
7119261079SEd Maste }
7219261079SEd Maste }
7319261079SEd Maste }
7419261079SEd Maste
7519261079SEd Maste static int
run_kex(struct test_state * ts,struct ssh * client,struct ssh * server)7619261079SEd Maste run_kex(struct test_state *ts, struct ssh *client, struct ssh *server)
7719261079SEd Maste {
7819261079SEd Maste int r = 0;
7919261079SEd Maste size_t cn, sn;
8019261079SEd Maste
8119261079SEd Maste /* If fuzzing, replace server/client input */
8219261079SEd Maste if (ts->sin != NULL) {
8319261079SEd Maste if ((r = ssh_input_append(server, sshbuf_ptr(ts->sin),
8419261079SEd Maste sshbuf_len(ts->sin))) != 0) {
8519261079SEd Maste error_fr(r, "ssh_input_append");
8619261079SEd Maste return r;
8719261079SEd Maste }
8819261079SEd Maste sshbuf_reset(ts->sin);
8919261079SEd Maste }
9019261079SEd Maste if (ts->cin != NULL) {
9119261079SEd Maste if ((r = ssh_input_append(client, sshbuf_ptr(ts->cin),
9219261079SEd Maste sshbuf_len(ts->cin))) != 0) {
9319261079SEd Maste error_fr(r, "ssh_input_append");
9419261079SEd Maste return r;
9519261079SEd Maste }
9619261079SEd Maste sshbuf_reset(ts->cin);
9719261079SEd Maste }
9819261079SEd Maste while (!server->kex->done || !client->kex->done) {
9919261079SEd Maste cn = sn = 0;
10019261079SEd Maste debug_f("S:");
10119261079SEd Maste if ((r = do_send_and_receive(server, client,
10219261079SEd Maste ts->smsgs, ts->cin != NULL, &sn)) != 0) {
10319261079SEd Maste debug_fr(r, "S->C");
10419261079SEd Maste break;
10519261079SEd Maste }
10619261079SEd Maste debug_f("C:");
10719261079SEd Maste if ((r = do_send_and_receive(client, server,
10819261079SEd Maste ts->cmsgs, ts->sin != NULL, &cn)) != 0) {
10919261079SEd Maste debug_fr(r, "C->S");
11019261079SEd Maste break;
11119261079SEd Maste }
11219261079SEd Maste if (cn == 0 && sn == 0) {
11319261079SEd Maste debug_f("kex stalled");
11419261079SEd Maste r = SSH_ERR_PROTOCOL_ERROR;
11519261079SEd Maste break;
11619261079SEd Maste }
11719261079SEd Maste }
11819261079SEd Maste debug_fr(r, "done");
11919261079SEd Maste return r;
12019261079SEd Maste }
12119261079SEd Maste
12219261079SEd Maste static void
store_key(struct shared_state * st,struct sshkey * pubkey,struct sshkey * privkey)12319261079SEd Maste store_key(struct shared_state *st, struct sshkey *pubkey,
12419261079SEd Maste struct sshkey *privkey)
12519261079SEd Maste {
12619261079SEd Maste if (st == NULL || pubkey->type < 0 || pubkey->type > INT_MAX ||
12719261079SEd Maste privkey->type != pubkey->type ||
12819261079SEd Maste ((size_t)pubkey->type < st->nkeys &&
12919261079SEd Maste st->pubkeys[pubkey->type] != NULL))
13019261079SEd Maste abort();
13119261079SEd Maste if ((size_t)pubkey->type >= st->nkeys) {
13219261079SEd Maste st->pubkeys = (struct sshkey **)xrecallocarray(st->pubkeys,
13319261079SEd Maste st->nkeys, pubkey->type + 1, sizeof(*st->pubkeys));
13419261079SEd Maste st->privkeys = (struct sshkey **)xrecallocarray(st->privkeys,
13519261079SEd Maste st->nkeys, privkey->type + 1, sizeof(*st->privkeys));
13619261079SEd Maste st->nkeys = privkey->type + 1;
13719261079SEd Maste }
13819261079SEd Maste debug_f("store %s at %d", sshkey_ssh_name(pubkey), pubkey->type);
13919261079SEd Maste st->pubkeys[pubkey->type] = pubkey;
14019261079SEd Maste st->privkeys[privkey->type] = privkey;
14119261079SEd Maste }
14219261079SEd Maste
14319261079SEd Maste static int
prepare_keys(struct shared_state * st)14419261079SEd Maste prepare_keys(struct shared_state *st)
14519261079SEd Maste {
14619261079SEd Maste if (prepare_key(st, KEY_RSA, 2048) != 0 ||
14719261079SEd Maste prepare_key(st, KEY_DSA, 1024) != 0 ||
14819261079SEd Maste prepare_key(st, KEY_ECDSA, 256) != 0 ||
14919261079SEd Maste prepare_key(st, KEY_ED25519, 256) != 0) {
15019261079SEd Maste error_f("key prepare failed");
15119261079SEd Maste return -1;
15219261079SEd Maste }
15319261079SEd Maste return 0;
15419261079SEd Maste }
15519261079SEd Maste
15619261079SEd Maste static struct sshkey *
get_pubkey(struct shared_state * st,int keytype)15719261079SEd Maste get_pubkey(struct shared_state *st, int keytype)
15819261079SEd Maste {
15919261079SEd Maste if (st == NULL || keytype < 0 || (size_t)keytype >= st->nkeys ||
16019261079SEd Maste st->pubkeys == NULL || st->pubkeys[keytype] == NULL)
16119261079SEd Maste abort();
16219261079SEd Maste return st->pubkeys[keytype];
16319261079SEd Maste }
16419261079SEd Maste
16519261079SEd Maste static struct sshkey *
get_privkey(struct shared_state * st,int keytype)16619261079SEd Maste get_privkey(struct shared_state *st, int keytype)
16719261079SEd Maste {
16819261079SEd Maste if (st == NULL || keytype < 0 || (size_t)keytype >= st->nkeys ||
16919261079SEd Maste st->privkeys == NULL || st->privkeys[keytype] == NULL)
17019261079SEd Maste abort();
17119261079SEd Maste return st->privkeys[keytype];
17219261079SEd Maste }
17319261079SEd Maste
17419261079SEd Maste static int
do_kex_with_key(struct shared_state * st,struct test_state * ts,const char * kex,int keytype)17519261079SEd Maste do_kex_with_key(struct shared_state *st, struct test_state *ts,
17619261079SEd Maste const char *kex, int keytype)
17719261079SEd Maste {
17819261079SEd Maste struct ssh *client = NULL, *server = NULL;
17919261079SEd Maste struct sshkey *privkey = NULL, *pubkey = NULL;
18019261079SEd Maste struct sshbuf *state = NULL;
18119261079SEd Maste struct kex_params kex_params;
18219261079SEd Maste const char *ccp, *proposal[PROPOSAL_MAX] = { KEX_CLIENT };
18319261079SEd Maste char *myproposal[PROPOSAL_MAX] = {0}, *keyname = NULL;
18419261079SEd Maste int i, r;
18519261079SEd Maste
18619261079SEd Maste ts->cin = ts->sin = NULL;
18719261079SEd Maste if (ts->c_template != NULL &&
18819261079SEd Maste (ts->cin = sshbuf_fromb(ts->c_template)) == NULL)
18919261079SEd Maste abort();
19019261079SEd Maste if (ts->s_template != NULL &&
19119261079SEd Maste (ts->sin = sshbuf_fromb(ts->s_template)) == NULL)
19219261079SEd Maste abort();
19319261079SEd Maste
19419261079SEd Maste pubkey = get_pubkey(st, keytype);
19519261079SEd Maste privkey = get_privkey(st, keytype);
19619261079SEd Maste keyname = xstrdup(sshkey_ssh_name(privkey));
19719261079SEd Maste if (ts->cin != NULL) {
19819261079SEd Maste debug_f("%s %s clobber client %zu", kex, keyname,
19919261079SEd Maste sshbuf_len(ts->cin));
20019261079SEd Maste } else if (ts->sin != NULL) {
20119261079SEd Maste debug_f("%s %s clobber server %zu", kex, keyname,
20219261079SEd Maste sshbuf_len(ts->sin));
20319261079SEd Maste } else
20419261079SEd Maste debug_f("%s %s noclobber", kex, keyname);
20519261079SEd Maste
20619261079SEd Maste for (i = 0; i < PROPOSAL_MAX; i++) {
20719261079SEd Maste ccp = proposal[i];
20819261079SEd Maste #ifdef CIPHER_NONE_AVAIL
20919261079SEd Maste if (i == PROPOSAL_ENC_ALGS_CTOS || i == PROPOSAL_ENC_ALGS_STOC)
21019261079SEd Maste ccp = "none";
21119261079SEd Maste #endif
21219261079SEd Maste if (i == PROPOSAL_SERVER_HOST_KEY_ALGS)
21319261079SEd Maste ccp = keyname;
21419261079SEd Maste else if (i == PROPOSAL_KEX_ALGS && kex != NULL)
21519261079SEd Maste ccp = kex;
21619261079SEd Maste if ((myproposal[i] = strdup(ccp)) == NULL) {
21719261079SEd Maste error_f("strdup prop %d", i);
21819261079SEd Maste goto fail;
21919261079SEd Maste }
22019261079SEd Maste }
22119261079SEd Maste memcpy(kex_params.proposal, myproposal, sizeof(myproposal));
22219261079SEd Maste if ((r = ssh_init(&client, 0, &kex_params)) != 0) {
22319261079SEd Maste error_fr(r, "init client");
22419261079SEd Maste goto fail;
22519261079SEd Maste }
22619261079SEd Maste if ((r = ssh_init(&server, 1, &kex_params)) != 0) {
22719261079SEd Maste error_fr(r, "init server");
22819261079SEd Maste goto fail;
22919261079SEd Maste }
23019261079SEd Maste if ((r = ssh_add_hostkey(server, privkey)) != 0 ||
23119261079SEd Maste (r = ssh_add_hostkey(client, pubkey)) != 0) {
23219261079SEd Maste error_fr(r, "add hostkeys");
23319261079SEd Maste goto fail;
23419261079SEd Maste }
23519261079SEd Maste if ((r = run_kex(ts, client, server)) != 0) {
23619261079SEd Maste error_fr(r, "kex");
23719261079SEd Maste goto fail;
23819261079SEd Maste }
23919261079SEd Maste /* XXX rekex, set_state, etc */
24019261079SEd Maste fail:
24119261079SEd Maste for (i = 0; i < PROPOSAL_MAX; i++)
24219261079SEd Maste free(myproposal[i]);
24319261079SEd Maste sshbuf_free(ts->sin);
24419261079SEd Maste sshbuf_free(ts->cin);
24519261079SEd Maste sshbuf_free(state);
24619261079SEd Maste ssh_free(client);
24719261079SEd Maste ssh_free(server);
24819261079SEd Maste free(keyname);
24919261079SEd Maste return r;
25019261079SEd Maste }
25119261079SEd Maste
25219261079SEd Maste static int
prepare_key(struct shared_state * st,int kt,int bits)25319261079SEd Maste prepare_key(struct shared_state *st, int kt, int bits)
25419261079SEd Maste {
25519261079SEd Maste const char *pubstr = NULL;
25619261079SEd Maste const char *privstr = NULL;
25719261079SEd Maste char *tmp, *cp;
25819261079SEd Maste struct sshkey *privkey = NULL, *pubkey = NULL;
25919261079SEd Maste struct sshbuf *b = NULL;
26019261079SEd Maste int r;
26119261079SEd Maste
26219261079SEd Maste switch (kt) {
26319261079SEd Maste case KEY_RSA:
26419261079SEd Maste pubstr = PUB_RSA;
26519261079SEd Maste privstr = PRIV_RSA;
26619261079SEd Maste break;
26719261079SEd Maste case KEY_DSA:
26819261079SEd Maste pubstr = PUB_DSA;
26919261079SEd Maste privstr = PRIV_DSA;
27019261079SEd Maste break;
27119261079SEd Maste case KEY_ECDSA:
27219261079SEd Maste pubstr = PUB_ECDSA;
27319261079SEd Maste privstr = PRIV_ECDSA;
27419261079SEd Maste break;
27519261079SEd Maste case KEY_ED25519:
27619261079SEd Maste pubstr = PUB_ED25519;
27719261079SEd Maste privstr = PRIV_ED25519;
27819261079SEd Maste break;
27919261079SEd Maste default:
28019261079SEd Maste abort();
28119261079SEd Maste }
28219261079SEd Maste if ((b = sshbuf_from(privstr, strlen(privstr))) == NULL)
28319261079SEd Maste abort();
28419261079SEd Maste if ((r = sshkey_parse_private_fileblob(b, "", &privkey, NULL)) != 0) {
28519261079SEd Maste error_fr(r, "priv %d", kt);
28619261079SEd Maste abort();
28719261079SEd Maste }
28819261079SEd Maste sshbuf_free(b);
28919261079SEd Maste tmp = cp = xstrdup(pubstr);
29019261079SEd Maste if ((pubkey = sshkey_new(KEY_UNSPEC)) == NULL)
29119261079SEd Maste abort();
29219261079SEd Maste if ((r = sshkey_read(pubkey, &cp)) != 0) {
29319261079SEd Maste error_fr(r, "pub %d", kt);
29419261079SEd Maste abort();
29519261079SEd Maste }
29619261079SEd Maste free(tmp);
29719261079SEd Maste
29819261079SEd Maste store_key(st, pubkey, privkey);
29919261079SEd Maste return 0;
30019261079SEd Maste }
30119261079SEd Maste
30219261079SEd Maste #if defined(STANDALONE)
30319261079SEd Maste
30419261079SEd Maste #if 0 /* use this if generating new keys to embed above */
30519261079SEd Maste static int
30619261079SEd Maste prepare_key(struct shared_state *st, int keytype, int bits)
30719261079SEd Maste {
30819261079SEd Maste struct sshkey *privkey = NULL, *pubkey = NULL;
30919261079SEd Maste int r;
31019261079SEd Maste
31119261079SEd Maste if ((r = sshkey_generate(keytype, bits, &privkey)) != 0) {
31219261079SEd Maste error_fr(r, "generate");
31319261079SEd Maste abort();
31419261079SEd Maste }
31519261079SEd Maste if ((r = sshkey_from_private(privkey, &pubkey)) != 0) {
31619261079SEd Maste error_fr(r, "make pubkey");
31719261079SEd Maste abort();
31819261079SEd Maste }
31919261079SEd Maste store_key(st, pubkey, privkey);
32019261079SEd Maste return 0;
32119261079SEd Maste }
32219261079SEd Maste #endif
32319261079SEd Maste
main(void)32419261079SEd Maste int main(void)
32519261079SEd Maste {
32619261079SEd Maste static struct shared_state *st;
32719261079SEd Maste struct test_state *ts;
32819261079SEd Maste const int keytypes[] = { KEY_RSA, KEY_DSA, KEY_ECDSA, KEY_ED25519, -1 };
329*1323ec57SEd Maste static const char * const kextypes[] = {
33019261079SEd Maste "sntrup761x25519-sha512@openssh.com",
33119261079SEd Maste "curve25519-sha256@libssh.org",
33219261079SEd Maste "ecdh-sha2-nistp256",
33319261079SEd Maste "diffie-hellman-group1-sha1",
33419261079SEd Maste "diffie-hellman-group-exchange-sha1",
33519261079SEd Maste NULL,
33619261079SEd Maste };
33719261079SEd Maste int i, j;
33819261079SEd Maste char *path;
33919261079SEd Maste FILE *f;
34019261079SEd Maste
34119261079SEd Maste log_init("kex_fuzz", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 1);
34219261079SEd Maste
34319261079SEd Maste if (st == NULL) {
34419261079SEd Maste st = (struct shared_state *)xcalloc(1, sizeof(*st));
34519261079SEd Maste prepare_keys(st);
34619261079SEd Maste }
34719261079SEd Maste /* Run each kex method for each key and save client/server packets */
34819261079SEd Maste for (i = 0; keytypes[i] != -1; i++) {
34919261079SEd Maste for (j = 0; kextypes[j] != NULL; j++) {
35019261079SEd Maste ts = (struct test_state *)xcalloc(1, sizeof(*ts));
35119261079SEd Maste ts->smsgs = sshbuf_new();
35219261079SEd Maste ts->cmsgs = sshbuf_new();
35319261079SEd Maste do_kex_with_key(st, ts, kextypes[j], keytypes[i]);
35419261079SEd Maste xasprintf(&path, "S2C-%s-%s",
35519261079SEd Maste kextypes[j], sshkey_type(st->pubkeys[keytypes[i]]));
35619261079SEd Maste debug_f("%s", path);
35719261079SEd Maste if ((f = fopen(path, "wb+")) == NULL)
35819261079SEd Maste abort();
35919261079SEd Maste if (fwrite(sshbuf_ptr(ts->smsgs), 1,
36019261079SEd Maste sshbuf_len(ts->smsgs), f) != sshbuf_len(ts->smsgs))
36119261079SEd Maste abort();
36219261079SEd Maste fclose(f);
36319261079SEd Maste free(path);
36419261079SEd Maste //sshbuf_dump(ts->smsgs, stderr);
36519261079SEd Maste xasprintf(&path, "C2S-%s-%s",
36619261079SEd Maste kextypes[j], sshkey_type(st->pubkeys[keytypes[i]]));
36719261079SEd Maste debug_f("%s", path);
36819261079SEd Maste if ((f = fopen(path, "wb+")) == NULL)
36919261079SEd Maste abort();
37019261079SEd Maste if (fwrite(sshbuf_ptr(ts->cmsgs), 1,
37119261079SEd Maste sshbuf_len(ts->cmsgs), f) != sshbuf_len(ts->cmsgs))
37219261079SEd Maste abort();
37319261079SEd Maste fclose(f);
37419261079SEd Maste free(path);
37519261079SEd Maste //sshbuf_dump(ts->cmsgs, stderr);
37619261079SEd Maste sshbuf_free(ts->smsgs);
37719261079SEd Maste sshbuf_free(ts->cmsgs);
37819261079SEd Maste free(ts);
37919261079SEd Maste }
38019261079SEd Maste }
38119261079SEd Maste for (i = 0; keytypes[i] != -1; i++) {
38219261079SEd Maste xasprintf(&path, "%s.priv",
38319261079SEd Maste sshkey_type(st->privkeys[keytypes[i]]));
38419261079SEd Maste debug_f("%s", path);
38519261079SEd Maste if (sshkey_save_private(st->privkeys[keytypes[i]], path,
38619261079SEd Maste "", "", SSHKEY_PRIVATE_OPENSSH, NULL, 0) != 0)
38719261079SEd Maste abort();
38819261079SEd Maste free(path);
38919261079SEd Maste xasprintf(&path, "%s.pub",
39019261079SEd Maste sshkey_type(st->pubkeys[keytypes[i]]));
39119261079SEd Maste debug_f("%s", path);
39219261079SEd Maste if (sshkey_save_public(st->pubkeys[keytypes[i]], path, "") != 0)
39319261079SEd Maste abort();
39419261079SEd Maste free(path);
39519261079SEd Maste }
39619261079SEd Maste }
39719261079SEd Maste #else /* !STANDALONE */
39819261079SEd Maste static void
do_kex(struct shared_state * st,struct test_state * ts,const char * kex)39919261079SEd Maste do_kex(struct shared_state *st, struct test_state *ts, const char *kex)
40019261079SEd Maste {
40119261079SEd Maste do_kex_with_key(st, ts, kex, KEY_RSA);
40219261079SEd Maste do_kex_with_key(st, ts, kex, KEY_DSA);
40319261079SEd Maste do_kex_with_key(st, ts, kex, KEY_ECDSA);
40419261079SEd Maste do_kex_with_key(st, ts, kex, KEY_ED25519);
40519261079SEd Maste }
40619261079SEd Maste
40719261079SEd Maste static void
kex_tests(struct shared_state * st,struct test_state * ts)40819261079SEd Maste kex_tests(struct shared_state *st, struct test_state *ts)
40919261079SEd Maste {
41019261079SEd Maste do_kex(st, ts, "sntrup761x25519-sha512@openssh.com");
41119261079SEd Maste do_kex(st, ts, "curve25519-sha256@libssh.org");
41219261079SEd Maste do_kex(st, ts, "ecdh-sha2-nistp256");
41319261079SEd Maste do_kex(st, ts, "diffie-hellman-group1-sha1");
41419261079SEd Maste do_kex(st, ts, "diffie-hellman-group-exchange-sha1");
41519261079SEd Maste }
41619261079SEd Maste
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)41719261079SEd Maste int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
41819261079SEd Maste {
41919261079SEd Maste static struct shared_state *st;
42019261079SEd Maste struct test_state *ts;
42119261079SEd Maste u_char crbuf[SSH_MAX_PRE_BANNER_LINES * 4];
42219261079SEd Maste u_char zbuf[4096] = {0};
42319261079SEd Maste static LogLevel loglevel = SYSLOG_LEVEL_INFO;
42419261079SEd Maste
42519261079SEd Maste if (st == NULL) {
42619261079SEd Maste if (getenv("DEBUG") != NULL || getenv("KEX_FUZZ_DEBUG") != NULL)
42719261079SEd Maste loglevel = SYSLOG_LEVEL_DEBUG3;
42819261079SEd Maste log_init("kex_fuzz",
42919261079SEd Maste loglevel, SYSLOG_FACILITY_AUTH, 1);
43019261079SEd Maste st = (struct shared_state *)xcalloc(1, sizeof(*st));
43119261079SEd Maste prepare_keys(st);
43219261079SEd Maste }
43319261079SEd Maste
43419261079SEd Maste /* Ensure that we can complete (fail) banner exchange at least */
43519261079SEd Maste memset(crbuf, '\n', sizeof(crbuf));
43619261079SEd Maste
43719261079SEd Maste ts = (struct test_state *)xcalloc(1, sizeof(*ts));
43819261079SEd Maste if ((ts->s_template = sshbuf_new()) == NULL ||
43919261079SEd Maste sshbuf_put(ts->s_template, data, size) != 0 ||
44019261079SEd Maste sshbuf_put(ts->s_template, crbuf, sizeof(crbuf)) != 0 ||
44119261079SEd Maste sshbuf_put(ts->s_template, zbuf, sizeof(zbuf)) != 0)
44219261079SEd Maste abort();
44319261079SEd Maste kex_tests(st, ts);
44419261079SEd Maste sshbuf_free(ts->s_template);
44519261079SEd Maste free(ts);
44619261079SEd Maste
44719261079SEd Maste ts = (struct test_state *)xcalloc(1, sizeof(*ts));
44819261079SEd Maste if ((ts->c_template = sshbuf_new()) == NULL ||
44919261079SEd Maste sshbuf_put(ts->c_template, data, size) != 0 ||
45019261079SEd Maste sshbuf_put(ts->c_template, crbuf, sizeof(crbuf)) != 0 ||
45119261079SEd Maste sshbuf_put(ts->c_template, zbuf, sizeof(zbuf)) != 0)
45219261079SEd Maste abort();
45319261079SEd Maste kex_tests(st, ts);
45419261079SEd Maste sshbuf_free(ts->c_template);
45519261079SEd Maste free(ts);
45619261079SEd Maste
45719261079SEd Maste return 0;
45819261079SEd Maste }
45919261079SEd Maste #endif /* STANDALONE */
46019261079SEd Maste } /* extern "C" */
461