1#include <string.h> 2#include <stdlib.h> 3#include <stdint.h> 4#include "common.h" 5#include "mbedtls/ssl.h" 6#if defined(MBEDTLS_SSL_PROTO_DTLS) 7#include "mbedtls/entropy.h" 8#include "mbedtls/ctr_drbg.h" 9#include "mbedtls/timing.h" 10#include "test/certs.h" 11 12#if defined(MBEDTLS_SSL_CLI_C) && \ 13 defined(MBEDTLS_ENTROPY_C) && \ 14 defined(MBEDTLS_CTR_DRBG_C) && \ 15 defined(MBEDTLS_TIMING_C) 16static int initialized = 0; 17#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) 18static mbedtls_x509_crt cacert; 19#endif 20 21const char *pers = "fuzz_dtlsclient"; 22#endif 23#endif // MBEDTLS_SSL_PROTO_DTLS 24 25 26 27int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) 28{ 29#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ 30 defined(MBEDTLS_SSL_CLI_C) && \ 31 defined(MBEDTLS_ENTROPY_C) && \ 32 defined(MBEDTLS_CTR_DRBG_C) && \ 33 defined(MBEDTLS_TIMING_C) 34 int ret; 35 size_t len; 36 mbedtls_ssl_context ssl; 37 mbedtls_ssl_config conf; 38 mbedtls_ctr_drbg_context ctr_drbg; 39 mbedtls_entropy_context entropy; 40 mbedtls_timing_delay_context timer; 41 unsigned char buf[4096]; 42 fuzzBufferOffset_t biomemfuzz; 43 44 if (initialized == 0) { 45#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) 46 mbedtls_x509_crt_init(&cacert); 47 if (mbedtls_x509_crt_parse(&cacert, (const unsigned char *) mbedtls_test_cas_pem, 48 mbedtls_test_cas_pem_len) != 0) { 49 return 1; 50 } 51#endif 52 dummy_init(); 53 54 initialized = 1; 55 } 56 57 mbedtls_ssl_init(&ssl); 58 mbedtls_ssl_config_init(&conf); 59 mbedtls_ctr_drbg_init(&ctr_drbg); 60 mbedtls_entropy_init(&entropy); 61 62#if defined(MBEDTLS_USE_PSA_CRYPTO) 63 psa_status_t status = psa_crypto_init(); 64 if (status != PSA_SUCCESS) { 65 goto exit; 66 } 67#endif /* MBEDTLS_USE_PSA_CRYPTO */ 68 69 srand(1); 70 if (mbedtls_ctr_drbg_seed(&ctr_drbg, dummy_entropy, &entropy, 71 (const unsigned char *) pers, strlen(pers)) != 0) { 72 goto exit; 73 } 74 75 if (mbedtls_ssl_config_defaults(&conf, 76 MBEDTLS_SSL_IS_CLIENT, 77 MBEDTLS_SSL_TRANSPORT_DATAGRAM, 78 MBEDTLS_SSL_PRESET_DEFAULT) != 0) { 79 goto exit; 80 } 81 82#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) 83 mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); 84#endif 85 mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE); 86 mbedtls_ssl_conf_rng(&conf, dummy_random, &ctr_drbg); 87 88 if (mbedtls_ssl_setup(&ssl, &conf) != 0) { 89 goto exit; 90 } 91 92 mbedtls_ssl_set_timer_cb(&ssl, &timer, mbedtls_timing_set_delay, 93 mbedtls_timing_get_delay); 94 95#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) 96 if (mbedtls_ssl_set_hostname(&ssl, "localhost") != 0) { 97 goto exit; 98 } 99#endif 100 101 biomemfuzz.Data = Data; 102 biomemfuzz.Size = Size; 103 biomemfuzz.Offset = 0; 104 mbedtls_ssl_set_bio(&ssl, &biomemfuzz, dummy_send, fuzz_recv, fuzz_recv_timeout); 105 106 ret = mbedtls_ssl_handshake(&ssl); 107 if (ret == 0) { 108 //keep reading data from server until the end 109 do { 110 len = sizeof(buf) - 1; 111 ret = mbedtls_ssl_read(&ssl, buf, len); 112 113 if (ret == MBEDTLS_ERR_SSL_WANT_READ) { 114 continue; 115 } else if (ret <= 0) { 116 //EOF or error 117 break; 118 } 119 } while (1); 120 } 121 122exit: 123 mbedtls_entropy_free(&entropy); 124 mbedtls_ctr_drbg_free(&ctr_drbg); 125 mbedtls_ssl_config_free(&conf); 126 mbedtls_ssl_free(&ssl); 127#if defined(MBEDTLS_USE_PSA_CRYPTO) 128 mbedtls_psa_crypto_free(); 129#endif /* MBEDTLS_USE_PSA_CRYPTO */ 130 131#else 132 (void) Data; 133 (void) Size; 134#endif 135 return 0; 136} 137