Lain Iwakura d31cbb3a7c
Some checks failed
CIFuzz / Fuzzing (push) Waiting to run
C/C++ CI self-hosted / win10 cygwin-release (push) Waiting to run
C/C++ CI self-hosted / ARM default (push) Waiting to run
C/C++ CI self-hosted / ARM64 default (push) Waiting to run
C/C++ CI self-hosted / alpine default (push) Waiting to run
C/C++ CI self-hosted / centos7 default (push) Waiting to run
C/C++ CI self-hosted / debian-i386 default (push) Waiting to run
C/C++ CI self-hosted / dfly30 default (push) Waiting to run
C/C++ CI self-hosted / dfly48 default (push) Waiting to run
C/C++ CI self-hosted / dfly60 default (push) Waiting to run
C/C++ CI self-hosted / dfly62 default (push) Waiting to run
C/C++ CI self-hosted / dfly64 default (push) Waiting to run
C/C++ CI self-hosted / fbsd10 default (push) Waiting to run
C/C++ CI self-hosted / fbsd12 default (push) Waiting to run
C/C++ CI self-hosted / fbsd13 default (push) Waiting to run
C/C++ CI self-hosted / fbsd14 default (push) Waiting to run
C/C++ CI self-hosted / nbsd10 default (push) Waiting to run
C/C++ CI self-hosted / nbsd3 default (push) Waiting to run
C/C++ CI self-hosted / nbsd4 default (push) Waiting to run
C/C++ CI self-hosted / nbsd8 default (push) Waiting to run
C/C++ CI self-hosted / nbsd9 default (push) Waiting to run
C/C++ CI self-hosted / obsd51 default (push) Waiting to run
C/C++ CI self-hosted / obsd67 default (push) Waiting to run
C/C++ CI self-hosted / obsd72 default (push) Waiting to run
C/C++ CI self-hosted / obsd73 default (push) Waiting to run
C/C++ CI self-hosted / obsd74 default (push) Waiting to run
C/C++ CI self-hosted / obsdsnap default (push) Waiting to run
C/C++ CI self-hosted / obsdsnap-i386 default (push) Waiting to run
C/C++ CI self-hosted / omnios default (push) Waiting to run
C/C++ CI self-hosted / openindiana default (push) Waiting to run
C/C++ CI self-hosted / ubuntu-2204 default (push) Waiting to run
C/C++ CI self-hosted / obsd-arm64 default (push) Waiting to run
C/C++ CI self-hosted / aix51 default (push) Waiting to run
C/C++ CI self-hosted / fbsd14-ppc64 default (push) Waiting to run
C/C++ CI self-hosted / sol10 default (push) Waiting to run
C/C++ CI self-hosted / sol11 default (push) Waiting to run
C/C++ CI self-hosted / win10 default (push) Waiting to run
C/C++ CI self-hosted / debian-riscv64 default (push) Waiting to run
C/C++ CI self-hosted / openwrt-mips default (push) Waiting to run
C/C++ CI self-hosted / openwrt-mipsel default (push) Waiting to run
C/C++ CI self-hosted / ARM64 pam (push) Waiting to run
C/C++ CI self-hosted / centos7 pam (push) Waiting to run
C/C++ CI self-hosted / debian-i386 pam (push) Waiting to run
C/C++ CI self-hosted / dfly48 pam (push) Waiting to run
C/C++ CI self-hosted / dfly58 pam (push) Waiting to run
C/C++ CI self-hosted / dfly60 pam (push) Waiting to run
C/C++ CI self-hosted / dfly62 pam (push) Waiting to run
C/C++ CI self-hosted / dfly64 pam (push) Waiting to run
C/C++ CI self-hosted / fbsd10 pam (push) Waiting to run
C/C++ CI self-hosted / fbsd12 pam (push) Waiting to run
C/C++ CI self-hosted / fbsd13 pam (push) Waiting to run
C/C++ CI self-hosted / fbsd14 pam (push) Waiting to run
C/C++ CI self-hosted / nbsd10 pam (push) Waiting to run
C/C++ CI self-hosted / nbsd8 pam (push) Waiting to run
C/C++ CI self-hosted / nbsd9 pam (push) Waiting to run
C/C++ CI self-hosted / omnios pam (push) Waiting to run
C/C++ CI self-hosted / openindiana pam (push) Waiting to run
C/C++ CI self-hosted / sol10 pam (push) Waiting to run
C/C++ CI self-hosted / sol11 pam-krb5 (push) Waiting to run
C/C++ CI self-hosted / sol11 sol64 (push) Waiting to run
C/C++ CI self-hosted / dfly30 without-openssl (push) Waiting to run
C/C++ CI / ubuntu-latest aws-lc (push) Failing after 31s
C/C++ CI / ubuntu-latest boringssl (push) Failing after 31s
C/C++ CI / ubuntu-latest clang-15 (push) Failing after 31s
C/C++ CI / ubuntu-latest clang-19 (push) Failing after 19s
C/C++ CI / ubuntu-latest default (push) Failing after 3s
C/C++ CI / ubuntu-latest gcc-14 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-3.2.6 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-3.3.6 (push) Failing after 3s
C/C++ CI / ubuntu-latest libressl-3.4.3 (push) Failing after 3s
C/C++ CI / ubuntu-latest libressl-3.5.3 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-3.6.1 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-3.7.2 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-3.8.4 (push) Failing after 3s
C/C++ CI / ubuntu-latest libressl-3.9.2 (push) Failing after 3s
C/C++ CI / ubuntu-latest libressl-4.0.0 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-master (push) Failing after 4s
C/C++ CI / ubuntu-latest musl (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-1.1.1 (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-1.1.1_stable (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-1.1.1t (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-1.1.1w (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-3.0 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.0.0 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.0.15 (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-3.1 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.1.0 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.1.7 (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-3.2 (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-3.2.3 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.3 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.3.2 (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-3.4.0 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-master (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-noec (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.71 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.72 (push) Failing after 3s
C/C++ CI / ubuntu-latest putty-0.73 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.74 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.75 (push) Failing after 3s
C/C++ CI / ubuntu-latest putty-0.76 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.77 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.78 (push) Failing after 3s
C/C++ CI / ubuntu-latest putty-0.79 (push) Failing after 3s
C/C++ CI / ubuntu-latest putty-0.80 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.81 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.82 (push) Failing after 3s
C/C++ CI / ubuntu-latest putty-0.83 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-snapshot (push) Failing after 4s
C/C++ CI / ubuntu-latest tcmalloc (push) Failing after 3s
C/C++ CI / ubuntu-latest zlib-develop (push) Failing after 3s
C/C++ CI / ubuntu-22.04 c89 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 clang-11 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 clang-12-Werror (push) Has been cancelled
C/C++ CI / ubuntu-22.04 clang-14 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 clang-sanitize-address (push) Has been cancelled
C/C++ CI / ubuntu-22.04 clang-sanitize-undefined (push) Has been cancelled
C/C++ CI / windows-2019 cygwin-release (push) Has been cancelled
C/C++ CI / windows-2022 cygwin-release (push) Has been cancelled
C/C++ CI / macos-13 default (push) Has been cancelled
C/C++ CI / macos-14 default (push) Has been cancelled
C/C++ CI / macos-15 default (push) Has been cancelled
C/C++ CI / ubuntu-22.04 default (push) Has been cancelled
C/C++ CI / ubuntu-22.04-arm default (push) Has been cancelled
C/C++ CI / ubuntu-24.04-arm default (push) Has been cancelled
C/C++ CI / windows-2019 default (push) Has been cancelled
C/C++ CI / windows-2022 default (push) Has been cancelled
C/C++ CI / ubuntu-22.04 gcc-11-Werror (push) Has been cancelled
C/C++ CI / ubuntu-22.04 gcc-12-Werror (push) Has been cancelled
C/C++ CI / ubuntu-22.04 gcc-9 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 gcc-sanitize-address (push) Has been cancelled
C/C++ CI / ubuntu-22.04 gcc-sanitize-undefined (push) Has been cancelled
C/C++ CI / ubuntu-22.04 hardenedmalloc (push) Has been cancelled
C/C++ CI / ubuntu-22.04 heimdal (push) Has been cancelled
C/C++ CI / ubuntu-22.04 kitchensink (push) Has been cancelled
C/C++ CI / ubuntu-22.04-arm kitchensink (push) Has been cancelled
C/C++ CI / ubuntu-24.04-arm kitchensink (push) Has been cancelled
C/C++ CI / ubuntu-22.04 krb5 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 libedit (push) Has been cancelled
C/C++ CI / macos-13 pam (push) Has been cancelled
C/C++ CI / macos-14 pam (push) Has been cancelled
C/C++ CI / macos-15 pam (push) Has been cancelled
C/C++ CI / ubuntu-22.04 pam (push) Has been cancelled
C/C++ CI / ubuntu-22.04 selinux (push) Has been cancelled
C/C++ CI / ubuntu-22.04 sk (push) Has been cancelled
C/C++ CI / ubuntu-22.04 valgrind-1 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 valgrind-2 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 valgrind-3 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 valgrind-4 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 valgrind-unit (push) Has been cancelled
C/C++ CI / ubuntu-22.04 without-openssl (push) Has been cancelled
original code
2025-07-12 18:35:29 +03:00

455 lines
12 KiB
C++

// libfuzzer driver for key exchange fuzzing.
#include <sys/types.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
extern "C" {
#include "includes.h"
#include "ssherr.h"
#include "ssh_api.h"
#include "sshbuf.h"
#include "packet.h"
#include "myproposal.h"
#include "xmalloc.h"
#include "authfile.h"
#include "log.h"
#include "fixed-keys.h"
// Define if you want to generate traces.
/* #define STANDALONE 1 */
static int prepare_key(struct shared_state *st, int keytype, int bits);
struct shared_state {
size_t nkeys;
struct sshkey **privkeys, **pubkeys;
};
struct test_state {
struct sshbuf *smsgs, *cmsgs; /* output, for standalone mode */
struct sshbuf *sin, *cin; /* input; setup per-test in do_kex_with_key */
struct sshbuf *s_template, *c_template; /* main copy of input */
};
static int
do_send_and_receive(struct ssh *from, struct ssh *to,
struct sshbuf *store, int clobber, size_t *n)
{
u_char type;
size_t len;
const u_char *buf;
int r;
for (*n = 0;; (*n)++) {
if ((r = ssh_packet_next(from, &type)) != 0) {
debug_fr(r, "ssh_packet_next");
return r;
}
if (type != 0)
return 0;
buf = ssh_output_ptr(from, &len);
debug_f("%zu%s", len, clobber ? " ignore" : "");
if (len == 0)
return 0;
if ((r = ssh_output_consume(from, len)) != 0) {
debug_fr(r, "ssh_output_consume");
return r;
}
if (store != NULL && (r = sshbuf_put(store, buf, len)) != 0) {
debug_fr(r, "sshbuf_put");
return r;
}
if (!clobber && (r = ssh_input_append(to, buf, len)) != 0) {
debug_fr(r, "ssh_input_append");
return r;
}
}
}
static int
run_kex(struct test_state *ts, struct ssh *client, struct ssh *server)
{
int r = 0;
size_t cn, sn;
/* If fuzzing, replace server/client input */
if (ts->sin != NULL) {
if ((r = ssh_input_append(server, sshbuf_ptr(ts->sin),
sshbuf_len(ts->sin))) != 0) {
error_fr(r, "ssh_input_append");
return r;
}
sshbuf_reset(ts->sin);
}
if (ts->cin != NULL) {
if ((r = ssh_input_append(client, sshbuf_ptr(ts->cin),
sshbuf_len(ts->cin))) != 0) {
error_fr(r, "ssh_input_append");
return r;
}
sshbuf_reset(ts->cin);
}
while (!server->kex->done || !client->kex->done) {
cn = sn = 0;
debug_f("S:");
if ((r = do_send_and_receive(server, client,
ts->smsgs, ts->cin != NULL, &sn)) != 0) {
debug_fr(r, "S->C");
break;
}
debug_f("C:");
if ((r = do_send_and_receive(client, server,
ts->cmsgs, ts->sin != NULL, &cn)) != 0) {
debug_fr(r, "C->S");
break;
}
if (cn == 0 && sn == 0) {
debug_f("kex stalled");
r = SSH_ERR_PROTOCOL_ERROR;
break;
}
}
debug_fr(r, "done");
return r;
}
static void
store_key(struct shared_state *st, struct sshkey *pubkey,
struct sshkey *privkey)
{
if (st == NULL || pubkey->type < 0 || pubkey->type > INT_MAX ||
privkey->type != pubkey->type ||
((size_t)pubkey->type < st->nkeys &&
st->pubkeys[pubkey->type] != NULL))
abort();
if ((size_t)pubkey->type >= st->nkeys) {
st->pubkeys = (struct sshkey **)xrecallocarray(st->pubkeys,
st->nkeys, pubkey->type + 1, sizeof(*st->pubkeys));
st->privkeys = (struct sshkey **)xrecallocarray(st->privkeys,
st->nkeys, privkey->type + 1, sizeof(*st->privkeys));
st->nkeys = privkey->type + 1;
}
debug_f("store %s at %d", sshkey_ssh_name(pubkey), pubkey->type);
st->pubkeys[pubkey->type] = pubkey;
st->privkeys[privkey->type] = privkey;
}
static int
prepare_keys(struct shared_state *st)
{
if (prepare_key(st, KEY_RSA, 2048) != 0 ||
prepare_key(st, KEY_ECDSA, 256) != 0 ||
prepare_key(st, KEY_ED25519, 256) != 0) {
error_f("key prepare failed");
return -1;
}
return 0;
}
static struct sshkey *
get_pubkey(struct shared_state *st, int keytype)
{
if (st == NULL || keytype < 0 || (size_t)keytype >= st->nkeys ||
st->pubkeys == NULL || st->pubkeys[keytype] == NULL)
abort();
return st->pubkeys[keytype];
}
static struct sshkey *
get_privkey(struct shared_state *st, int keytype)
{
if (st == NULL || keytype < 0 || (size_t)keytype >= st->nkeys ||
st->privkeys == NULL || st->privkeys[keytype] == NULL)
abort();
return st->privkeys[keytype];
}
static int
do_kex_with_key(struct shared_state *st, struct test_state *ts,
const char *kex, int keytype)
{
struct ssh *client = NULL, *server = NULL;
struct sshkey *privkey = NULL, *pubkey = NULL;
struct sshbuf *state = NULL;
struct kex_params kex_params;
const char *ccp, *proposal[PROPOSAL_MAX] = { KEX_CLIENT };
char *myproposal[PROPOSAL_MAX] = {0}, *keyname = NULL;
int i, r;
ts->cin = ts->sin = NULL;
if (ts->c_template != NULL &&
(ts->cin = sshbuf_fromb(ts->c_template)) == NULL)
abort();
if (ts->s_template != NULL &&
(ts->sin = sshbuf_fromb(ts->s_template)) == NULL)
abort();
pubkey = get_pubkey(st, keytype);
privkey = get_privkey(st, keytype);
keyname = xstrdup(sshkey_ssh_name(privkey));
if (ts->cin != NULL) {
debug_f("%s %s clobber client %zu", kex, keyname,
sshbuf_len(ts->cin));
} else if (ts->sin != NULL) {
debug_f("%s %s clobber server %zu", kex, keyname,
sshbuf_len(ts->sin));
} else
debug_f("%s %s noclobber", kex, keyname);
for (i = 0; i < PROPOSAL_MAX; i++) {
ccp = proposal[i];
#ifdef CIPHER_NONE_AVAIL
if (i == PROPOSAL_ENC_ALGS_CTOS || i == PROPOSAL_ENC_ALGS_STOC)
ccp = "none";
#endif
if (i == PROPOSAL_SERVER_HOST_KEY_ALGS)
ccp = keyname;
else if (i == PROPOSAL_KEX_ALGS && kex != NULL)
ccp = kex;
if ((myproposal[i] = strdup(ccp)) == NULL) {
error_f("strdup prop %d", i);
goto fail;
}
}
memcpy(kex_params.proposal, myproposal, sizeof(myproposal));
if ((r = ssh_init(&client, 0, &kex_params)) != 0) {
error_fr(r, "init client");
goto fail;
}
if ((r = ssh_init(&server, 1, &kex_params)) != 0) {
error_fr(r, "init server");
goto fail;
}
if ((r = ssh_add_hostkey(server, privkey)) != 0 ||
(r = ssh_add_hostkey(client, pubkey)) != 0) {
error_fr(r, "add hostkeys");
goto fail;
}
if ((r = run_kex(ts, client, server)) != 0) {
error_fr(r, "kex");
goto fail;
}
/* XXX rekex, set_state, etc */
fail:
for (i = 0; i < PROPOSAL_MAX; i++)
free(myproposal[i]);
sshbuf_free(ts->sin);
sshbuf_free(ts->cin);
sshbuf_free(state);
ssh_free(client);
ssh_free(server);
free(keyname);
return r;
}
static int
prepare_key(struct shared_state *st, int kt, int bits)
{
const char *pubstr = NULL;
const char *privstr = NULL;
char *tmp, *cp;
struct sshkey *privkey = NULL, *pubkey = NULL;
struct sshbuf *b = NULL;
int r;
switch (kt) {
case KEY_RSA:
pubstr = PUB_RSA;
privstr = PRIV_RSA;
break;
case KEY_ECDSA:
pubstr = PUB_ECDSA;
privstr = PRIV_ECDSA;
break;
case KEY_ED25519:
pubstr = PUB_ED25519;
privstr = PRIV_ED25519;
break;
default:
abort();
}
if ((b = sshbuf_from(privstr, strlen(privstr))) == NULL)
abort();
if ((r = sshkey_parse_private_fileblob(b, "", &privkey, NULL)) != 0) {
error_fr(r, "priv %d", kt);
abort();
}
sshbuf_free(b);
tmp = cp = xstrdup(pubstr);
if ((pubkey = sshkey_new(KEY_UNSPEC)) == NULL)
abort();
if ((r = sshkey_read(pubkey, &cp)) != 0) {
error_fr(r, "pub %d", kt);
abort();
}
free(tmp);
store_key(st, pubkey, privkey);
return 0;
}
#if defined(STANDALONE)
#if 0 /* use this if generating new keys to embed above */
static int
prepare_key(struct shared_state *st, int keytype, int bits)
{
struct sshkey *privkey = NULL, *pubkey = NULL;
int r;
if ((r = sshkey_generate(keytype, bits, &privkey)) != 0) {
error_fr(r, "generate");
abort();
}
if ((r = sshkey_from_private(privkey, &pubkey)) != 0) {
error_fr(r, "make pubkey");
abort();
}
store_key(st, pubkey, privkey);
return 0;
}
#endif
int main(void)
{
static struct shared_state *st;
struct test_state *ts;
const int keytypes[] = { KEY_RSA, KEY_ECDSA, KEY_ED25519, -1 };
static const char * const kextypes[] = {
"sntrup761x25519-sha512@openssh.com",
"curve25519-sha256@libssh.org",
"ecdh-sha2-nistp256",
"diffie-hellman-group1-sha1",
"diffie-hellman-group-exchange-sha1",
NULL,
};
int i, j;
char *path;
FILE *f;
log_init("kex_fuzz", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 1);
if (st == NULL) {
st = (struct shared_state *)xcalloc(1, sizeof(*st));
prepare_keys(st);
}
/* Run each kex method for each key and save client/server packets */
for (i = 0; keytypes[i] != -1; i++) {
for (j = 0; kextypes[j] != NULL; j++) {
ts = (struct test_state *)xcalloc(1, sizeof(*ts));
ts->smsgs = sshbuf_new();
ts->cmsgs = sshbuf_new();
do_kex_with_key(st, ts, kextypes[j], keytypes[i]);
xasprintf(&path, "S2C-%s-%s",
kextypes[j], sshkey_type(st->pubkeys[keytypes[i]]));
debug_f("%s", path);
if ((f = fopen(path, "wb+")) == NULL)
abort();
if (fwrite(sshbuf_ptr(ts->smsgs), 1,
sshbuf_len(ts->smsgs), f) != sshbuf_len(ts->smsgs))
abort();
fclose(f);
free(path);
//sshbuf_dump(ts->smsgs, stderr);
xasprintf(&path, "C2S-%s-%s",
kextypes[j], sshkey_type(st->pubkeys[keytypes[i]]));
debug_f("%s", path);
if ((f = fopen(path, "wb+")) == NULL)
abort();
if (fwrite(sshbuf_ptr(ts->cmsgs), 1,
sshbuf_len(ts->cmsgs), f) != sshbuf_len(ts->cmsgs))
abort();
fclose(f);
free(path);
//sshbuf_dump(ts->cmsgs, stderr);
sshbuf_free(ts->smsgs);
sshbuf_free(ts->cmsgs);
free(ts);
}
}
for (i = 0; keytypes[i] != -1; i++) {
xasprintf(&path, "%s.priv",
sshkey_type(st->privkeys[keytypes[i]]));
debug_f("%s", path);
if (sshkey_save_private(st->privkeys[keytypes[i]], path,
"", "", SSHKEY_PRIVATE_OPENSSH, NULL, 0) != 0)
abort();
free(path);
xasprintf(&path, "%s.pub",
sshkey_type(st->pubkeys[keytypes[i]]));
debug_f("%s", path);
if (sshkey_save_public(st->pubkeys[keytypes[i]], path, "") != 0)
abort();
free(path);
}
}
#else /* !STANDALONE */
static void
do_kex(struct shared_state *st, struct test_state *ts, const char *kex)
{
do_kex_with_key(st, ts, kex, KEY_RSA);
do_kex_with_key(st, ts, kex, KEY_ECDSA);
do_kex_with_key(st, ts, kex, KEY_ED25519);
}
static void
kex_tests(struct shared_state *st, struct test_state *ts)
{
do_kex(st, ts, "sntrup761x25519-sha512@openssh.com");
do_kex(st, ts, "curve25519-sha256@libssh.org");
do_kex(st, ts, "ecdh-sha2-nistp256");
do_kex(st, ts, "diffie-hellman-group1-sha1");
do_kex(st, ts, "diffie-hellman-group-exchange-sha1");
}
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
static struct shared_state *st;
struct test_state *ts;
u_char crbuf[SSH_MAX_PRE_BANNER_LINES * 4];
u_char zbuf[4096] = {0};
static LogLevel loglevel = SYSLOG_LEVEL_INFO;
if (st == NULL) {
if (getenv("DEBUG") != NULL || getenv("KEX_FUZZ_DEBUG") != NULL)
loglevel = SYSLOG_LEVEL_DEBUG3;
log_init("kex_fuzz",
loglevel, SYSLOG_FACILITY_AUTH, 1);
st = (struct shared_state *)xcalloc(1, sizeof(*st));
prepare_keys(st);
}
/* Ensure that we can complete (fail) banner exchange at least */
memset(crbuf, '\n', sizeof(crbuf));
ts = (struct test_state *)xcalloc(1, sizeof(*ts));
if ((ts->s_template = sshbuf_new()) == NULL ||
sshbuf_put(ts->s_template, data, size) != 0 ||
sshbuf_put(ts->s_template, crbuf, sizeof(crbuf)) != 0 ||
sshbuf_put(ts->s_template, zbuf, sizeof(zbuf)) != 0)
abort();
kex_tests(st, ts);
sshbuf_free(ts->s_template);
free(ts);
ts = (struct test_state *)xcalloc(1, sizeof(*ts));
if ((ts->c_template = sshbuf_new()) == NULL ||
sshbuf_put(ts->c_template, data, size) != 0 ||
sshbuf_put(ts->c_template, crbuf, sizeof(crbuf)) != 0 ||
sshbuf_put(ts->c_template, zbuf, sizeof(zbuf)) != 0)
abort();
kex_tests(st, ts);
sshbuf_free(ts->c_template);
free(ts);
return 0;
}
#endif /* STANDALONE */
} /* extern "C" */