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)) 19const char *pers = "fuzz_dtlsserver"; 20const unsigned char client_ip[4] = { 0x7F, 0, 0, 1 }; 21static int initialized = 0; 22#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) 23static mbedtls_x509_crt srvcert; 24static mbedtls_pk_context pkey; 25#endif 26#endif 27#endif // MBEDTLS_SSL_PROTO_DTLS 28 29int 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 162exit: 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