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