blob: 783cd48433bae0409687393bde946cba1cad4914 [file] [log] [blame]
Philippe Antoine72333522018-05-03 16:40:24 +02001#include "mbedtls/ssl.h"
2#include "mbedtls/entropy.h"
3#include "mbedtls/ctr_drbg.h"
4#include "mbedtls/certs.h"
Philippe Antoine08633822019-06-04 14:03:06 +02005#include "common.h"
Philippe Antoine72333522018-05-03 16:40:24 +02006#include <string.h>
7#include <stdlib.h>
8#include <stdbool.h>
9#include <stdint.h>
10
11
12static bool initialized = 0;
13#if defined(MBEDTLS_X509_CRT_PARSE_C)
14static mbedtls_x509_crt cacert;
15#endif
16const char *alpn_list[3];
17
18
19#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
20const unsigned char psk[] = {
21 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
22 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
23};
24const char psk_id[] = "Client_identity";
25#endif
26
27const char *pers = "fuzz_client";
28
29
30typedef struct fuzzBufferOffset
31{
32 const uint8_t *Data;
33 size_t Size;
34 size_t Offset;
35} fuzzBufferOffset_t;
36
37static int dummy_send( void *ctx, const unsigned char *buf, size_t len )
38{
39 //silence warning about unused parameter
40 (void) ctx;
41 (void) buf;
42
43 //pretends we wrote everything ok
44 return( len );
45}
46
47static int fuzz_recv( void *ctx, unsigned char *buf, size_t len )
48{
49 //reads from the buffer from fuzzer
50 fuzzBufferOffset_t * biomemfuzz = (fuzzBufferOffset_t *) ctx;
51
52 if (biomemfuzz->Offset == biomemfuzz->Size) {
53 //EOF
54 return (0);
55 }
56 if (len + biomemfuzz->Offset > biomemfuzz->Size) {
57 //do not overflow
58 len = biomemfuzz->Size - biomemfuzz->Offset;
59 }
60 memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len);
61 biomemfuzz->Offset += len;
62 return( len );
63}
64
65static int dummy_random( void *p_rng, unsigned char *output, size_t output_len )
66{
67 int ret;
68 size_t i;
69
70 //use mbedtls_ctr_drbg_random to find bugs in it
71 ret = mbedtls_ctr_drbg_random(p_rng, output, output_len);
72 for (i=0; i<output_len; i++) {
73 //replace result with pseudo random
Philippe Antoine2b7c9a22019-06-04 12:05:36 +020074 output[i] = (unsigned char) rand();
Philippe Antoine72333522018-05-03 16:40:24 +020075 }
76 return( ret );
77}
78
79static int dummy_entropy( void *data, unsigned char *output, size_t len )
80{
Philippe Antoine72333522018-05-03 16:40:24 +020081 size_t i;
Philippe Antoinef0493042019-06-04 12:01:51 +020082 (void) data;
Philippe Antoine72333522018-05-03 16:40:24 +020083
84 //use mbedtls_entropy_func to find bugs in it
Philippe Antoine9c7b6982018-05-29 17:00:39 +020085 //test performance impact of entropy
86 //ret = mbedtls_entropy_func(data, output, len);
Philippe Antoine72333522018-05-03 16:40:24 +020087 for (i=0; i<len; i++) {
88 //replace result with pseudo random
Philippe Antoine2b7c9a22019-06-04 12:05:36 +020089 output[i] = (unsigned char) rand();
Philippe Antoine72333522018-05-03 16:40:24 +020090 }
Philippe Antoine9c7b6982018-05-29 17:00:39 +020091 return( 0 );
Philippe Antoine72333522018-05-03 16:40:24 +020092}
93
Philippe Antoine72333522018-05-03 16:40:24 +020094int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
95 int ret;
96 size_t len;
97 mbedtls_ssl_context ssl;
98 mbedtls_ssl_config conf;
99 mbedtls_ctr_drbg_context ctr_drbg;
100 mbedtls_entropy_context entropy;
101 unsigned char buf[4096];
102 fuzzBufferOffset_t biomemfuzz;
103 uint16_t options;
104
105 if (initialized == 0) {
106#if defined(MBEDTLS_X509_CRT_PARSE_C)
107 mbedtls_x509_crt_init( &cacert );
108 if (mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem,
109 mbedtls_test_cas_pem_len ) != 0)
110 return 1;
111#endif
112
113 alpn_list[0] = "HTTP";
114 alpn_list[1] = "fuzzalpn";
115 alpn_list[2] = NULL;
116
Philippe Antoine08633822019-06-04 14:03:06 +0200117 dummy_init();
118
Philippe Antoine72333522018-05-03 16:40:24 +0200119 initialized = 1;
120 }
121
122 //we take 1 byte as options input
123 if (Size < 2) {
124 return 0;
125 }
126 options = (Data[Size - 2] << 8) | Data[Size - 1];
127 //Avoid warnings if compile options imply no options
128 (void) options;
129
130 mbedtls_ssl_init( &ssl );
131 mbedtls_ssl_config_init( &conf );
132 mbedtls_ctr_drbg_init( &ctr_drbg );
133 mbedtls_entropy_init( &entropy );
134
135 if( mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy, &entropy,
136 (const unsigned char *) pers, strlen( pers ) ) != 0 )
137 goto exit;
138
139 if( mbedtls_ssl_config_defaults( &conf,
140 MBEDTLS_SSL_IS_CLIENT,
141 MBEDTLS_SSL_TRANSPORT_STREAM,
142 MBEDTLS_SSL_PRESET_DEFAULT ) != 0 )
143 goto exit;
144
145#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
146 if (options & 2) {
147 mbedtls_ssl_conf_psk( &conf, psk, sizeof( psk ),
148 (const unsigned char *) psk_id, sizeof( psk_id ) - 1 );
149 }
150#endif
151
152#if defined(MBEDTLS_X509_CRT_PARSE_C)
153 if (options & 4) {
154 mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
155 mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED );
156 } else
157#endif
158 {
159 mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE );
160 }
161#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
162 mbedtls_ssl_conf_truncated_hmac( &conf, (options & 8) ? MBEDTLS_SSL_TRUNC_HMAC_ENABLED : MBEDTLS_SSL_TRUNC_HMAC_DISABLED);
163#endif
164#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
165 mbedtls_ssl_conf_extended_master_secret( &conf, (options & 0x10) ? MBEDTLS_SSL_EXTENDED_MS_DISABLED : MBEDTLS_SSL_EXTENDED_MS_ENABLED);
166#endif
167#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
168 mbedtls_ssl_conf_encrypt_then_mac( &conf, (options & 0x20) ? MBEDTLS_SSL_ETM_DISABLED : MBEDTLS_SSL_ETM_ENABLED);
169#endif
170#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
171 mbedtls_ssl_conf_cbc_record_splitting( &conf, (options & 0x40) ? MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED : MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED );
172#endif
173#if defined(MBEDTLS_SSL_RENEGOTIATION)
174 mbedtls_ssl_conf_renegotiation( &conf, (options & 0x80) ? MBEDTLS_SSL_RENEGOTIATION_ENABLED : MBEDTLS_SSL_RENEGOTIATION_DISABLED );
175#endif
176#if defined(MBEDTLS_SSL_SESSION_TICKETS)
177 mbedtls_ssl_conf_session_tickets( &conf, (options & 0x100) ? MBEDTLS_SSL_SESSION_TICKETS_DISABLED : MBEDTLS_SSL_SESSION_TICKETS_ENABLED );
178#endif
179#if defined(MBEDTLS_SSL_ALPN)
180 if (options & 0x200) {
181 mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list );
182 }
183#endif
184 //There may be other options to add :
185 // mbedtls_ssl_conf_cert_profile, mbedtls_ssl_conf_sig_hashes
186
Philippe Antoine2b7c9a22019-06-04 12:05:36 +0200187 srand(1);
Philippe Antoine72333522018-05-03 16:40:24 +0200188 mbedtls_ssl_conf_rng( &conf, dummy_random, &ctr_drbg );
189
190 if( mbedtls_ssl_setup( &ssl, &conf ) != 0 )
191 goto exit;
192
193#if defined(MBEDTLS_X509_CRT_PARSE_C)
194 if ((options & 1) == 0) {
195 if( mbedtls_ssl_set_hostname( &ssl, "localhost" ) != 0 )
196 goto exit;
197 }
198#endif
199
200 biomemfuzz.Data = Data;
201 biomemfuzz.Size = Size-2;
202 biomemfuzz.Offset = 0;
203 mbedtls_ssl_set_bio( &ssl, &biomemfuzz, dummy_send, fuzz_recv, NULL );
204
205 ret = mbedtls_ssl_handshake( &ssl );
206 if( ret == 0 )
207 {
208 //keep reading data from server until the end
209 do
210 {
211 len = sizeof( buf ) - 1;
212 ret = mbedtls_ssl_read( &ssl, buf, len );
213
214 if( ret == MBEDTLS_ERR_SSL_WANT_READ )
215 continue;
216 else if( ret <= 0 )
217 //EOF or error
218 break;
219 }
220 while( 1 );
221 }
222
223exit:
224 mbedtls_entropy_free( &entropy );
225 mbedtls_ctr_drbg_free( &ctr_drbg );
226 mbedtls_ssl_config_free( &conf );
227 mbedtls_ssl_free( &ssl );
228
229 return 0;
230}