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