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