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
attempt_parse_blob(u_char * blob,size_t len)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
onerror(void * fuzz)75 onerror(void *fuzz)
76 {
77 fprintf(stderr, "Failed during fuzz:\n");
78 fuzz_dump((struct fuzz *)fuzz);
79 }
80
81 void
sshbuf_getput_fuzz_tests(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