1 /* 	$OpenBSD: test_sshbuf_getput_fuzz.c,v 1.2 2014/05/02 02:54:00 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 	BIGNUM *bn;
36 #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
37 	EC_KEY *eck;
38 #endif
39 	u_char *s;
40 	size_t l;
41 	u_int8_t u8;
42 	u_int16_t u16;
43 	u_int32_t u32;
44 	u_int64_t u64;
45 
46 	p1 = sshbuf_new();
47 	ASSERT_PTR_NE(p1, NULL);
48 	ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0);
49 	sshbuf_get_u8(p1, &u8);
50 	sshbuf_get_u16(p1, &u16);
51 	sshbuf_get_u32(p1, &u32);
52 	sshbuf_get_u64(p1, &u64);
53 	if (sshbuf_get_string(p1, &s, &l) == 0) {
54 		bzero(s, l);
55 		free(s);
56 	}
57 	bn = BN_new();
58 	sshbuf_get_bignum1(p1, bn);
59 	BN_clear_free(bn);
60 	bn = BN_new();
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
69 	sshbuf_free(p1);
70 }
71 
72 
73 static void
74 onerror(void *fuzz)
75 {
76 	fprintf(stderr, "Failed during fuzz:\n");
77 	fuzz_dump((struct fuzz *)fuzz);
78 }
79 
80 void
81 sshbuf_getput_fuzz_tests(void)
82 {
83 	u_char blob[] = {
84 		/* u8 */
85 		0xd0,
86 		/* u16 */
87 		0xc0, 0xde,
88 		/* u32 */
89 		0xfa, 0xce, 0xde, 0xad,
90 		/* u64 */
91 		0xfe, 0xed, 0xac, 0x1d, 0x1f, 0x1c, 0xbe, 0xef,
92 		/* string */
93 		0x00, 0x00, 0x00, 0x09,
94 		'O', ' ', 'G', 'o', 'r', 'g', 'o', 'n', '!',
95 		/* bignum1 */
96 		0x79,
97 		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
98 		0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
99 		/* bignum2 */
100 		0x00, 0x00, 0x00, 0x14,
101 		0x00,
102 		0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80,
103 		0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00,
104 		0x7f, 0xff, 0x11,
105 		/* EC point (NIST-256 curve) */
106 		0x00, 0x00, 0x00, 0x41,
107 		0x04,
108 		0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06,
109 		0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57,
110 		0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86,
111 		0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99,
112 		0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b,
113 		0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2,
114 		0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47,
115 		0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4,
116 	};
117 	struct fuzz *fuzz;
118 
119 	TEST_START("fuzz blob parsing");
120 	fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_2_BIT_FLIP |
121 	    FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP |
122 	    FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, blob, sizeof(blob));
123 	TEST_ONERROR(onerror, fuzz);
124 	for(; !fuzz_done(fuzz); fuzz_next(fuzz))
125 		attempt_parse_blob(blob, sizeof(blob));
126 	fuzz_cleanup(fuzz);
127 	TEST_DONE();
128 	TEST_ONERROR(NULL, NULL);
129 }
130 
131