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 
30 void sshbuf_getput_fuzz_tests(void);
31 
32 static void
33 attempt_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 
75 static void
76 onerror(void *fuzz)
77 {
78 	fprintf(stderr, "Failed during fuzz:\n");
79 	fuzz_dump((struct fuzz *)fuzz);
80 }
81 
82 void
83 sshbuf_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