Line data Source code
1 : #if !FD_HAS_HOSTED
2 : #error "This target requires FD_HAS_HOSTED"
3 : #endif
4 :
5 : /* fuzz_tls parses fd_tls handshaking. The first few bytes are used as
6 : entropy to reconstruct a fake state. */
7 :
8 : #include "fd_tls.h"
9 : #include "fd_tls_estate.h"
10 : #include "test_tls_helper.h"
11 : #include "../../ballet/ed25519/fd_ed25519.h"
12 : #include "../../ballet/ed25519/fd_x25519.h"
13 : #include "../../ballet/x509/fd_x509_mock.h"
14 :
15 : #include <assert.h>
16 : #include <stdlib.h>
17 :
18 : static void
19 : _tls_secrets( void const * handshake,
20 : void const * recv_secret,
21 : void const * send_secret,
22 0 : uint encryption_level ) {
23 0 : (void)handshake;
24 0 : (void)recv_secret;
25 0 : (void)send_secret;
26 0 : (void)encryption_level;
27 0 : }
28 :
29 : static int
30 : _tls_sendmsg( void const * handshake,
31 : void const * record,
32 : ulong record_sz,
33 : uint encryption_level,
34 0 : int flush ) {
35 0 : (void)handshake;
36 0 : (void)record;
37 0 : (void)record_sz;
38 0 : (void)encryption_level;
39 0 : (void)flush;
40 0 : return 1;
41 0 : }
42 :
43 : static ulong
44 : _tls_quic_tp_self( void * handshake,
45 : uchar * quic_tp,
46 0 : ulong quic_tp_bufsz ) {
47 0 : (void)handshake;
48 0 : static uchar const tp_buf[] = { 0x01, 0x02, 0x47, 0xd0 };
49 0 : assert( quic_tp_bufsz >= sizeof(tp_buf) );
50 0 : fd_memcpy( quic_tp, tp_buf, sizeof(tp_buf) );
51 0 : return sizeof(tp_buf);
52 0 : }
53 :
54 : static void
55 : _tls_quic_tp_peer( void * handshake,
56 : uchar const * quic_tp,
57 0 : ulong quic_tp_sz ) {
58 0 : (void)handshake;
59 0 : (void)quic_tp;
60 0 : (void)quic_tp_sz;
61 0 : }
62 :
63 : static fd_tls_t tls_tmpl[1] = {{
64 : .secrets_fn = _tls_secrets,
65 : .sendmsg_fn = _tls_sendmsg,
66 : .quic_tp_self_fn = _tls_quic_tp_self,
67 : .quic_tp_peer_fn = _tls_quic_tp_peer,
68 :
69 : .alpn = "\xasolana-tpu",
70 : .alpn_sz = 11U,
71 : }};
72 :
73 : int
74 : LLVMFuzzerInitialize( int * argc,
75 : char *** argv ) {
76 : /* Set up shell without signal handlers */
77 : putenv( "FD_LOG_BACKTRACE=0" );
78 : fd_boot( argc, argv );
79 : atexit( fd_halt );
80 : fd_log_level_core_set(3); /* crash on warning log */
81 :
82 : fd_rng_t _rng[1]; fd_rng_t * rng = fd_rng_join( fd_rng_new( _rng, 1000U, 0UL ) );
83 :
84 : for( ulong b=0; b<32UL; b++ ) tls_tmpl->kex_private_key[b] = fd_rng_uchar( rng );
85 : fd_x25519_public( tls_tmpl->kex_public_key, tls_tmpl->kex_private_key );
86 :
87 : fd_tls_test_sign_ctx_t sign_ctx[1];
88 : fd_tls_test_sign_ctx( sign_ctx, rng );
89 : tls_tmpl->sign = fd_tls_test_sign( &sign_ctx );
90 : fd_memcpy( tls_tmpl->cert_public_key, sign_ctx->public_key, 32UL );
91 : fd_x509_mock_cert( tls_tmpl->cert_x509, tls_tmpl->cert_public_key );
92 : tls_tmpl->cert_x509_sz = FD_X509_MOCK_CERT_SZ;
93 :
94 : fd_rng_delete( fd_rng_leave( rng ) );
95 : return 0;
96 : }
97 :
98 : /* Could be a bitmap */
99 :
100 : static uchar
101 : _tls_valid_srv_hs_state[ 16 ] = {
102 : [FD_TLS_HS_FAIL ] = 1,
103 : [FD_TLS_HS_CONNECTED ] = 1,
104 : [FD_TLS_HS_START ] = 1,
105 : [FD_TLS_HS_WAIT_CERT ] = 1,
106 : [FD_TLS_HS_WAIT_CV ] = 1,
107 : [FD_TLS_HS_WAIT_FINISHED] = 1
108 : };
109 :
110 : static uchar
111 : _tls_valid_cli_hs_state[ 16 ] = {
112 : [FD_TLS_HS_FAIL ] = 1,
113 : [FD_TLS_HS_CONNECTED ] = 1,
114 : [FD_TLS_HS_START ] = 1,
115 : [FD_TLS_HS_WAIT_SH ] = 1,
116 : [FD_TLS_HS_WAIT_EE ] = 1,
117 : [FD_TLS_HS_WAIT_CERT_CR ] = 1,
118 : [FD_TLS_HS_WAIT_CERT ] = 1,
119 : [FD_TLS_HS_WAIT_CV ] = 1,
120 : [FD_TLS_HS_WAIT_FINISHED] = 1
121 : };
122 :
123 : int
124 : LLVMFuzzerTestOneInput( uchar const * input,
125 : ulong input_sz ) {
126 :
127 : fd_rng_t _rng[1]; fd_rng_t * rng = fd_rng_join( fd_rng_new( _rng, 1001U, 0UL ) );
128 :
129 : if( input_sz<8UL ) return -1;
130 : ulong state = FD_LOAD( ulong, input );
131 :
132 : uchar const * payload = input + 8UL;
133 : ulong payload_sz = input_sz - 8UL;
134 :
135 : int is_server = !!( state & (1UL<< 0) );
136 : int has_alpn = !!( state & (1UL<< 1) );
137 : int has_x509 = !!( state & (1UL<< 2) );
138 : int is_quic = !!( state & (1UL<< 3) );
139 : uchar hs_state = (uchar)( ( state>> 4 )&0xFUL );
140 : int srv_rpk = !!( state & (1UL<< 8) );
141 : int cli_rpk = !!( state & (1UL<< 9) );
142 : int cli_cert = !!( state & (1UL<<10) );
143 : uint enc_lvl = (uint)( ( state>>11 )&0x3UL );
144 :
145 : fd_tls_t tls[1]; fd_memcpy( tls, tls_tmpl, sizeof(fd_tls_t) );
146 : tls->rand = fd_tls_test_rand( rng );
147 : tls->quic = (uchar)(is_quic&1);
148 : if( !has_alpn ) tls->alpn_sz = 0UL;
149 : if( !has_x509 ) tls->cert_x509_sz = 0UL;
150 :
151 : fd_tls_estate_base_t base = {
152 : .state = hs_state,
153 : .server = (uchar)( is_server&1 ),
154 : };
155 : for( ulong b=0; b<32UL; b++ ) base.client_random[b] = fd_rng_uchar( rng );
156 :
157 : if( is_server ) {
158 : if( !_tls_valid_srv_hs_state[ hs_state ] ) return -1;
159 : fd_tls_estate_srv_t hs[1] = {{
160 : .base = base,
161 : .server_cert_rpk = (uchar)(srv_rpk &1),
162 : .client_cert = (uchar)(cli_cert&1),
163 : .client_cert_rpk = (uchar)(cli_rpk &1),
164 : }};
165 : fd_tls_server_handshake( tls, hs, payload, payload_sz, enc_lvl );
166 : } else {
167 : if( !_tls_valid_cli_hs_state[ hs_state ] ) return -1;
168 : fd_tls_estate_cli_t hs[1] = {{
169 : .base = base,
170 : .server_cert_rpk = (uchar)(srv_rpk &1),
171 : .client_cert = (uchar)(cli_cert&1),
172 : .client_cert_rpk = (uchar)(cli_rpk &1),
173 : }};
174 : fd_tls_client_handshake( tls, hs, payload, payload_sz, enc_lvl );
175 : }
176 :
177 : fd_rng_delete( fd_rng_leave( rng ) );
178 : return 0;
179 : }
|