1/* 	$OpenBSD: test_sshbuf_getput_fuzz.c,v 1.5 2021/12/14 21:25:27 deraadt Exp $ */
2/*
3 * Regress test for sshbuf.h buffer API
4 *
5 * Placed in the public domain
6 */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <stdio.h>
12#ifdef HAVE_STDINT_H
13# include <stdint.h>
14#endif
15#include <stdlib.h>
16#include <string.h>
17
18#ifdef WITH_OPENSSL
19#include <openssl/bn.h>
20#include <openssl/objects.h>
21#ifdef OPENSSL_HAS_NISTP256
22# include <openssl/ec.h>
23#endif
24#endif
25
26#include "../test_helper/test_helper.h"
27#include "ssherr.h"
28#include "sshbuf.h"
29
30void sshbuf_getput_fuzz_tests(void);
31
32static void
33attempt_parse_blob(u_char *blob, size_t len)
34{
35	struct sshbuf *p1;
36#ifdef WITH_OPENSSL
37	BIGNUM *bn;
38#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
39	EC_KEY *eck;
40#endif /* defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) */
41#endif /* WITH_OPENSSL */
42	u_char *s;
43	size_t l;
44	u_int8_t u8;
45	u_int16_t u16;
46	u_int32_t u32;
47	u_int64_t u64;
48
49	p1 = sshbuf_new();
50	ASSERT_PTR_NE(p1, NULL);
51	ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0);
52	sshbuf_get_u8(p1, &u8);
53	sshbuf_get_u16(p1, &u16);
54	sshbuf_get_u32(p1, &u32);
55	sshbuf_get_u64(p1, &u64);
56	if (sshbuf_get_string(p1, &s, &l) == 0) {
57		bzero(s, l);
58		free(s);
59	}
60#ifdef WITH_OPENSSL
61	bn = NULL;
62	sshbuf_get_bignum2(p1, &bn);
63	BN_clear_free(bn);
64#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
65	eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
66	ASSERT_PTR_NE(eck, NULL);
67	sshbuf_get_eckey(p1, eck);
68	EC_KEY_free(eck);
69#endif /* defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) */
70#endif /* WITH_OPENSSL */
71	sshbuf_free(p1);
72}
73
74
75static void
76onerror(void *fuzz)
77{
78	fprintf(stderr, "Failed during fuzz:\n");
79	fuzz_dump((struct fuzz *)fuzz);
80}
81
82void
83sshbuf_getput_fuzz_tests(void)
84{
85	u_char blob[] = {
86		/* u8 */
87		0xd0,
88		/* u16 */
89		0xc0, 0xde,
90		/* u32 */
91		0xfa, 0xce, 0xde, 0xad,
92		/* u64 */
93		0xfe, 0xed, 0xac, 0x1d, 0x1f, 0x1c, 0xbe, 0xef,
94		/* string */
95		0x00, 0x00, 0x00, 0x09,
96		'O', ' ', 'G', 'o', 'r', 'g', 'o', 'n', '!',
97		/* bignum2 */
98		0x00, 0x00, 0x00, 0x14,
99		0x00,
100		0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
101		0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
102		0x7f, 0xff, 0x11,
103		/* EC point (NIST-256 curve) */
104		0x00, 0x00, 0x00, 0x41,
105		0x04,
106		0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
107		0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
108		0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
109		0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
110		0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
111		0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
112		0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
113		0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4,
114	};
115	struct fuzz *fuzz;
116	u_int fuzzers = FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP |
117	    FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
118	    FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END;
119
120	if (test_is_fast())
121		fuzzers &= ~(FUZZ_2_BYTE_FLIP|FUZZ_2_BIT_FLIP);
122
123	TEST_START("fuzz blob parsing");
124	fuzz = fuzz_begin(fuzzers, blob, sizeof(blob));
125	TEST_ONERROR(onerror, fuzz);
126	for(; !fuzz_done(fuzz); fuzz_next(fuzz))
127		attempt_parse_blob(blob, sizeof(blob));
128	fuzz_cleanup(fuzz);
129	TEST_DONE();
130	TEST_ONERROR(NULL, NULL);
131}
132
133