1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include "common.h"
5 #include "mbedtls/ssl.h"
6 #include "test/certs.h"
7 #if defined(MBEDTLS_SSL_PROTO_DTLS)
8 #include "mbedtls/entropy.h"
9 #include "mbedtls/ctr_drbg.h"
10 #include "mbedtls/timing.h"
11 #include "mbedtls/ssl_cookie.h"
12
13 #if defined(MBEDTLS_SSL_SRV_C) && \
14 defined(MBEDTLS_ENTROPY_C) && \
15 defined(MBEDTLS_CTR_DRBG_C) && \
16 defined(MBEDTLS_TIMING_C) && \
17 (defined(MBEDTLS_MD_CAN_SHA384) || \
18 defined(MBEDTLS_MD_CAN_SHA256))
19 const char *pers = "fuzz_dtlsserver";
20 const unsigned char client_ip[4] = { 0x7F, 0, 0, 1 };
21 static int initialized = 0;
22 #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
23 static mbedtls_x509_crt srvcert;
24 static mbedtls_pk_context pkey;
25 #endif
26 #endif
27 #endif // MBEDTLS_SSL_PROTO_DTLS
28
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)29 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
30 {
31 #if defined(MBEDTLS_SSL_PROTO_DTLS) && \
32 defined(MBEDTLS_SSL_SRV_C) && \
33 defined(MBEDTLS_ENTROPY_C) && \
34 defined(MBEDTLS_CTR_DRBG_C) && \
35 defined(MBEDTLS_TIMING_C) && \
36 (defined(MBEDTLS_MD_CAN_SHA384) || \
37 defined(MBEDTLS_MD_CAN_SHA256))
38 int ret;
39 size_t len;
40 mbedtls_ssl_context ssl;
41 mbedtls_ssl_config conf;
42 mbedtls_ctr_drbg_context ctr_drbg;
43 mbedtls_entropy_context entropy;
44 mbedtls_timing_delay_context timer;
45 mbedtls_ssl_cookie_ctx cookie_ctx;
46 unsigned char buf[4096];
47 fuzzBufferOffset_t biomemfuzz;
48
49 mbedtls_ctr_drbg_init(&ctr_drbg);
50 mbedtls_entropy_init(&entropy);
51 #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
52 mbedtls_x509_crt_init(&srvcert);
53 mbedtls_pk_init(&pkey);
54 #endif
55 mbedtls_ssl_init(&ssl);
56 mbedtls_ssl_config_init(&conf);
57 mbedtls_ssl_cookie_init(&cookie_ctx);
58
59 #if defined(MBEDTLS_USE_PSA_CRYPTO)
60 psa_status_t status = psa_crypto_init();
61 if (status != PSA_SUCCESS) {
62 goto exit;
63 }
64 #endif /* MBEDTLS_USE_PSA_CRYPTO */
65
66 if (mbedtls_ctr_drbg_seed(&ctr_drbg, dummy_entropy, &entropy,
67 (const unsigned char *) pers, strlen(pers)) != 0) {
68 goto exit;
69 }
70
71 if (initialized == 0) {
72 #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
73
74 if (mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_srv_crt,
75 mbedtls_test_srv_crt_len) != 0) {
76 return 1;
77 }
78 if (mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_cas_pem,
79 mbedtls_test_cas_pem_len) != 0) {
80 return 1;
81 }
82 if (mbedtls_pk_parse_key(&pkey, (const unsigned char *) mbedtls_test_srv_key,
83 mbedtls_test_srv_key_len, NULL, 0,
84 dummy_random, &ctr_drbg) != 0) {
85 return 1;
86 }
87 #endif
88 dummy_init();
89
90 initialized = 1;
91 }
92
93 if (mbedtls_ssl_config_defaults(&conf,
94 MBEDTLS_SSL_IS_SERVER,
95 MBEDTLS_SSL_TRANSPORT_DATAGRAM,
96 MBEDTLS_SSL_PRESET_DEFAULT) != 0) {
97 goto exit;
98 }
99
100
101 srand(1);
102 mbedtls_ssl_conf_rng(&conf, dummy_random, &ctr_drbg);
103
104 #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
105 mbedtls_ssl_conf_ca_chain(&conf, srvcert.next, NULL);
106 if (mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey) != 0) {
107 goto exit;
108 }
109 #endif
110
111 if (mbedtls_ssl_cookie_setup(&cookie_ctx, dummy_random, &ctr_drbg) != 0) {
112 goto exit;
113 }
114
115 mbedtls_ssl_conf_dtls_cookies(&conf,
116 mbedtls_ssl_cookie_write,
117 mbedtls_ssl_cookie_check,
118 &cookie_ctx);
119
120 if (mbedtls_ssl_setup(&ssl, &conf) != 0) {
121 goto exit;
122 }
123
124 mbedtls_ssl_set_timer_cb(&ssl, &timer, mbedtls_timing_set_delay,
125 mbedtls_timing_get_delay);
126
127 biomemfuzz.Data = Data;
128 biomemfuzz.Size = Size;
129 biomemfuzz.Offset = 0;
130 mbedtls_ssl_set_bio(&ssl, &biomemfuzz, dummy_send, fuzz_recv, fuzz_recv_timeout);
131 if (mbedtls_ssl_set_client_transport_id(&ssl, client_ip, sizeof(client_ip)) != 0) {
132 goto exit;
133 }
134
135 ret = mbedtls_ssl_handshake(&ssl);
136
137 if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) {
138 biomemfuzz.Offset = ssl.MBEDTLS_PRIVATE(next_record_offset);
139 mbedtls_ssl_session_reset(&ssl);
140 mbedtls_ssl_set_bio(&ssl, &biomemfuzz, dummy_send, fuzz_recv, fuzz_recv_timeout);
141 if (mbedtls_ssl_set_client_transport_id(&ssl, client_ip, sizeof(client_ip)) != 0) {
142 goto exit;
143 }
144
145 ret = mbedtls_ssl_handshake(&ssl);
146
147 if (ret == 0) {
148 //keep reading data from server until the end
149 do {
150 len = sizeof(buf) - 1;
151 ret = mbedtls_ssl_read(&ssl, buf, len);
152 if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
153 continue;
154 } else if (ret <= 0) {
155 //EOF or error
156 break;
157 }
158 } while (1);
159 }
160 }
161
162 exit:
163 mbedtls_ssl_cookie_free(&cookie_ctx);
164 mbedtls_entropy_free(&entropy);
165 #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
166 mbedtls_pk_free(&pkey);
167 mbedtls_x509_crt_free(&srvcert);
168 #endif
169 mbedtls_ctr_drbg_free(&ctr_drbg);
170 mbedtls_ssl_config_free(&conf);
171 mbedtls_ssl_free(&ssl);
172 #if defined(MBEDTLS_USE_PSA_CRYPTO)
173 mbedtls_psa_crypto_free();
174 #endif /* MBEDTLS_USE_PSA_CRYPTO */
175
176 #else
177 (void) Data;
178 (void) Size;
179 #endif
180 return 0;
181 }
182