1*62c56f98SSadaf Ebrahimi #define MBEDTLS_ALLOW_PRIVATE_ACCESS
2*62c56f98SSadaf Ebrahimi
3*62c56f98SSadaf Ebrahimi #include "mbedtls/ssl.h"
4*62c56f98SSadaf Ebrahimi #include "mbedtls/entropy.h"
5*62c56f98SSadaf Ebrahimi #include "mbedtls/ctr_drbg.h"
6*62c56f98SSadaf Ebrahimi #include "test/certs.h"
7*62c56f98SSadaf Ebrahimi #include "common.h"
8*62c56f98SSadaf Ebrahimi #include <string.h>
9*62c56f98SSadaf Ebrahimi #include <stdlib.h>
10*62c56f98SSadaf Ebrahimi #include <stdint.h>
11*62c56f98SSadaf Ebrahimi
12*62c56f98SSadaf Ebrahimi
13*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_CLI_C) && \
14*62c56f98SSadaf Ebrahimi defined(MBEDTLS_ENTROPY_C) && \
15*62c56f98SSadaf Ebrahimi defined(MBEDTLS_CTR_DRBG_C)
16*62c56f98SSadaf Ebrahimi static int initialized = 0;
17*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
18*62c56f98SSadaf Ebrahimi static mbedtls_x509_crt cacert;
19*62c56f98SSadaf Ebrahimi #endif
20*62c56f98SSadaf Ebrahimi const char *alpn_list[3];
21*62c56f98SSadaf Ebrahimi
22*62c56f98SSadaf Ebrahimi
23*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
24*62c56f98SSadaf Ebrahimi const unsigned char psk[] = {
25*62c56f98SSadaf Ebrahimi 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
26*62c56f98SSadaf Ebrahimi 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
27*62c56f98SSadaf Ebrahimi };
28*62c56f98SSadaf Ebrahimi const char psk_id[] = "Client_identity";
29*62c56f98SSadaf Ebrahimi #endif
30*62c56f98SSadaf Ebrahimi
31*62c56f98SSadaf Ebrahimi const char *pers = "fuzz_client";
32*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
33*62c56f98SSadaf Ebrahimi
34*62c56f98SSadaf Ebrahimi
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)35*62c56f98SSadaf Ebrahimi int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
36*62c56f98SSadaf Ebrahimi {
37*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_CLI_C) && \
38*62c56f98SSadaf Ebrahimi defined(MBEDTLS_ENTROPY_C) && \
39*62c56f98SSadaf Ebrahimi defined(MBEDTLS_CTR_DRBG_C)
40*62c56f98SSadaf Ebrahimi int ret;
41*62c56f98SSadaf Ebrahimi size_t len;
42*62c56f98SSadaf Ebrahimi mbedtls_ssl_context ssl;
43*62c56f98SSadaf Ebrahimi mbedtls_ssl_config conf;
44*62c56f98SSadaf Ebrahimi mbedtls_ctr_drbg_context ctr_drbg;
45*62c56f98SSadaf Ebrahimi mbedtls_entropy_context entropy;
46*62c56f98SSadaf Ebrahimi unsigned char buf[4096];
47*62c56f98SSadaf Ebrahimi fuzzBufferOffset_t biomemfuzz;
48*62c56f98SSadaf Ebrahimi uint16_t options;
49*62c56f98SSadaf Ebrahimi
50*62c56f98SSadaf Ebrahimi if (initialized == 0) {
51*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
52*62c56f98SSadaf Ebrahimi mbedtls_x509_crt_init(&cacert);
53*62c56f98SSadaf Ebrahimi if (mbedtls_x509_crt_parse(&cacert, (const unsigned char *) mbedtls_test_cas_pem,
54*62c56f98SSadaf Ebrahimi mbedtls_test_cas_pem_len) != 0) {
55*62c56f98SSadaf Ebrahimi return 1;
56*62c56f98SSadaf Ebrahimi }
57*62c56f98SSadaf Ebrahimi #endif
58*62c56f98SSadaf Ebrahimi
59*62c56f98SSadaf Ebrahimi alpn_list[0] = "HTTP";
60*62c56f98SSadaf Ebrahimi alpn_list[1] = "fuzzalpn";
61*62c56f98SSadaf Ebrahimi alpn_list[2] = NULL;
62*62c56f98SSadaf Ebrahimi
63*62c56f98SSadaf Ebrahimi dummy_init();
64*62c56f98SSadaf Ebrahimi
65*62c56f98SSadaf Ebrahimi initialized = 1;
66*62c56f98SSadaf Ebrahimi }
67*62c56f98SSadaf Ebrahimi
68*62c56f98SSadaf Ebrahimi //we take 1 byte as options input
69*62c56f98SSadaf Ebrahimi if (Size < 2) {
70*62c56f98SSadaf Ebrahimi return 0;
71*62c56f98SSadaf Ebrahimi }
72*62c56f98SSadaf Ebrahimi options = (Data[Size - 2] << 8) | Data[Size - 1];
73*62c56f98SSadaf Ebrahimi //Avoid warnings if compile options imply no options
74*62c56f98SSadaf Ebrahimi (void) options;
75*62c56f98SSadaf Ebrahimi
76*62c56f98SSadaf Ebrahimi mbedtls_ssl_init(&ssl);
77*62c56f98SSadaf Ebrahimi mbedtls_ssl_config_init(&conf);
78*62c56f98SSadaf Ebrahimi mbedtls_ctr_drbg_init(&ctr_drbg);
79*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&entropy);
80*62c56f98SSadaf Ebrahimi
81*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
82*62c56f98SSadaf Ebrahimi psa_status_t status = psa_crypto_init();
83*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
84*62c56f98SSadaf Ebrahimi goto exit;
85*62c56f98SSadaf Ebrahimi }
86*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
87*62c56f98SSadaf Ebrahimi
88*62c56f98SSadaf Ebrahimi if (mbedtls_ctr_drbg_seed(&ctr_drbg, dummy_entropy, &entropy,
89*62c56f98SSadaf Ebrahimi (const unsigned char *) pers, strlen(pers)) != 0) {
90*62c56f98SSadaf Ebrahimi goto exit;
91*62c56f98SSadaf Ebrahimi }
92*62c56f98SSadaf Ebrahimi
93*62c56f98SSadaf Ebrahimi if (mbedtls_ssl_config_defaults(&conf,
94*62c56f98SSadaf Ebrahimi MBEDTLS_SSL_IS_CLIENT,
95*62c56f98SSadaf Ebrahimi MBEDTLS_SSL_TRANSPORT_STREAM,
96*62c56f98SSadaf Ebrahimi MBEDTLS_SSL_PRESET_DEFAULT) != 0) {
97*62c56f98SSadaf Ebrahimi goto exit;
98*62c56f98SSadaf Ebrahimi }
99*62c56f98SSadaf Ebrahimi
100*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
101*62c56f98SSadaf Ebrahimi if (options & 2) {
102*62c56f98SSadaf Ebrahimi mbedtls_ssl_conf_psk(&conf, psk, sizeof(psk),
103*62c56f98SSadaf Ebrahimi (const unsigned char *) psk_id, sizeof(psk_id) - 1);
104*62c56f98SSadaf Ebrahimi }
105*62c56f98SSadaf Ebrahimi #endif
106*62c56f98SSadaf Ebrahimi
107*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
108*62c56f98SSadaf Ebrahimi if (options & 4) {
109*62c56f98SSadaf Ebrahimi mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
110*62c56f98SSadaf Ebrahimi mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
111*62c56f98SSadaf Ebrahimi } else
112*62c56f98SSadaf Ebrahimi #endif
113*62c56f98SSadaf Ebrahimi {
114*62c56f98SSadaf Ebrahimi mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
115*62c56f98SSadaf Ebrahimi }
116*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
117*62c56f98SSadaf Ebrahimi mbedtls_ssl_conf_extended_master_secret(&conf,
118*62c56f98SSadaf Ebrahimi (options &
119*62c56f98SSadaf Ebrahimi 0x10) ? MBEDTLS_SSL_EXTENDED_MS_DISABLED : MBEDTLS_SSL_EXTENDED_MS_ENABLED);
120*62c56f98SSadaf Ebrahimi #endif
121*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
122*62c56f98SSadaf Ebrahimi mbedtls_ssl_conf_encrypt_then_mac(&conf,
123*62c56f98SSadaf Ebrahimi (options &
124*62c56f98SSadaf Ebrahimi 0x20) ? MBEDTLS_SSL_ETM_DISABLED : MBEDTLS_SSL_ETM_ENABLED);
125*62c56f98SSadaf Ebrahimi #endif
126*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
127*62c56f98SSadaf Ebrahimi mbedtls_ssl_conf_renegotiation(&conf,
128*62c56f98SSadaf Ebrahimi (options &
129*62c56f98SSadaf Ebrahimi 0x80) ? MBEDTLS_SSL_RENEGOTIATION_ENABLED : MBEDTLS_SSL_RENEGOTIATION_DISABLED);
130*62c56f98SSadaf Ebrahimi #endif
131*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SESSION_TICKETS)
132*62c56f98SSadaf Ebrahimi mbedtls_ssl_conf_session_tickets(&conf,
133*62c56f98SSadaf Ebrahimi (options &
134*62c56f98SSadaf Ebrahimi 0x100) ? MBEDTLS_SSL_SESSION_TICKETS_DISABLED : MBEDTLS_SSL_SESSION_TICKETS_ENABLED);
135*62c56f98SSadaf Ebrahimi #endif
136*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ALPN)
137*62c56f98SSadaf Ebrahimi if (options & 0x200) {
138*62c56f98SSadaf Ebrahimi mbedtls_ssl_conf_alpn_protocols(&conf, alpn_list);
139*62c56f98SSadaf Ebrahimi }
140*62c56f98SSadaf Ebrahimi #endif
141*62c56f98SSadaf Ebrahimi //There may be other options to add :
142*62c56f98SSadaf Ebrahimi // mbedtls_ssl_conf_cert_profile, mbedtls_ssl_conf_sig_hashes
143*62c56f98SSadaf Ebrahimi
144*62c56f98SSadaf Ebrahimi srand(1);
145*62c56f98SSadaf Ebrahimi mbedtls_ssl_conf_rng(&conf, dummy_random, &ctr_drbg);
146*62c56f98SSadaf Ebrahimi
147*62c56f98SSadaf Ebrahimi if (mbedtls_ssl_setup(&ssl, &conf) != 0) {
148*62c56f98SSadaf Ebrahimi goto exit;
149*62c56f98SSadaf Ebrahimi }
150*62c56f98SSadaf Ebrahimi
151*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
152*62c56f98SSadaf Ebrahimi if ((options & 1) == 0) {
153*62c56f98SSadaf Ebrahimi if (mbedtls_ssl_set_hostname(&ssl, "localhost") != 0) {
154*62c56f98SSadaf Ebrahimi goto exit;
155*62c56f98SSadaf Ebrahimi }
156*62c56f98SSadaf Ebrahimi }
157*62c56f98SSadaf Ebrahimi #endif
158*62c56f98SSadaf Ebrahimi
159*62c56f98SSadaf Ebrahimi biomemfuzz.Data = Data;
160*62c56f98SSadaf Ebrahimi biomemfuzz.Size = Size-2;
161*62c56f98SSadaf Ebrahimi biomemfuzz.Offset = 0;
162*62c56f98SSadaf Ebrahimi mbedtls_ssl_set_bio(&ssl, &biomemfuzz, dummy_send, fuzz_recv, NULL);
163*62c56f98SSadaf Ebrahimi
164*62c56f98SSadaf Ebrahimi ret = mbedtls_ssl_handshake(&ssl);
165*62c56f98SSadaf Ebrahimi if (ret == 0) {
166*62c56f98SSadaf Ebrahimi //keep reading data from server until the end
167*62c56f98SSadaf Ebrahimi do {
168*62c56f98SSadaf Ebrahimi len = sizeof(buf) - 1;
169*62c56f98SSadaf Ebrahimi ret = mbedtls_ssl_read(&ssl, buf, len);
170*62c56f98SSadaf Ebrahimi
171*62c56f98SSadaf Ebrahimi if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
172*62c56f98SSadaf Ebrahimi continue;
173*62c56f98SSadaf Ebrahimi } else if (ret <= 0) {
174*62c56f98SSadaf Ebrahimi //EOF or error
175*62c56f98SSadaf Ebrahimi break;
176*62c56f98SSadaf Ebrahimi }
177*62c56f98SSadaf Ebrahimi } while (1);
178*62c56f98SSadaf Ebrahimi }
179*62c56f98SSadaf Ebrahimi
180*62c56f98SSadaf Ebrahimi exit:
181*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&entropy);
182*62c56f98SSadaf Ebrahimi mbedtls_ctr_drbg_free(&ctr_drbg);
183*62c56f98SSadaf Ebrahimi mbedtls_ssl_config_free(&conf);
184*62c56f98SSadaf Ebrahimi mbedtls_ssl_free(&ssl);
185*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
186*62c56f98SSadaf Ebrahimi mbedtls_psa_crypto_free();
187*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
188*62c56f98SSadaf Ebrahimi
189*62c56f98SSadaf Ebrahimi #else
190*62c56f98SSadaf Ebrahimi (void) Data;
191*62c56f98SSadaf Ebrahimi (void) Size;
192*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
193*62c56f98SSadaf Ebrahimi
194*62c56f98SSadaf Ebrahimi return 0;
195*62c56f98SSadaf Ebrahimi }
196