1#include "mbedtls/ssl.h" 2#include "mbedtls/entropy.h" 3#include "mbedtls/ctr_drbg.h" 4#include "mbedtls/ssl_ticket.h" 5#include "test/certs.h" 6#include "common.h" 7#include <string.h> 8#include <stdlib.h> 9#include <stdint.h> 10 11 12#if defined(MBEDTLS_SSL_SRV_C) && \ 13 defined(MBEDTLS_ENTROPY_C) && \ 14 defined(MBEDTLS_CTR_DRBG_C) 15const char *pers = "fuzz_server"; 16static int initialized = 0; 17#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) 18static mbedtls_x509_crt srvcert; 19static mbedtls_pk_context pkey; 20#endif 21const char *alpn_list[3]; 22 23#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 24const unsigned char psk[] = { 25 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 26 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f 27}; 28const char psk_id[] = "Client_identity"; 29#endif 30#endif // MBEDTLS_SSL_SRV_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_SRV_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#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C) 45 mbedtls_ssl_ticket_context ticket_ctx; 46#endif 47 unsigned char buf[4096]; 48 fuzzBufferOffset_t biomemfuzz; 49 uint8_t options; 50 51 //we take 1 byte as options input 52 if (Size < 1) { 53 return 0; 54 } 55 options = Data[Size - 1]; 56 57 mbedtls_ctr_drbg_init(&ctr_drbg); 58 mbedtls_entropy_init(&entropy); 59#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) 60 mbedtls_x509_crt_init(&srvcert); 61 mbedtls_pk_init(&pkey); 62#endif 63 mbedtls_ssl_init(&ssl); 64 mbedtls_ssl_config_init(&conf); 65#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C) 66 mbedtls_ssl_ticket_init(&ticket_ctx); 67#endif 68#if defined(MBEDTLS_USE_PSA_CRYPTO) 69 psa_status_t status = psa_crypto_init(); 70 if (status != PSA_SUCCESS) { 71 goto exit; 72 } 73#endif /* MBEDTLS_USE_PSA_CRYPTO */ 74 75 if (mbedtls_ctr_drbg_seed(&ctr_drbg, dummy_entropy, &entropy, 76 (const unsigned char *) pers, strlen(pers)) != 0) { 77 return 1; 78 } 79 80 if (initialized == 0) { 81 82#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) 83 if (mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_srv_crt, 84 mbedtls_test_srv_crt_len) != 0) { 85 return 1; 86 } 87 if (mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_cas_pem, 88 mbedtls_test_cas_pem_len) != 0) { 89 return 1; 90 } 91 if (mbedtls_pk_parse_key(&pkey, (const unsigned char *) mbedtls_test_srv_key, 92 mbedtls_test_srv_key_len, NULL, 0, 93 dummy_random, &ctr_drbg) != 0) { 94 return 1; 95 } 96#endif 97 98 alpn_list[0] = "HTTP"; 99 alpn_list[1] = "fuzzalpn"; 100 alpn_list[2] = NULL; 101 102 dummy_init(); 103 104 initialized = 1; 105 } 106 107 if (mbedtls_ssl_config_defaults(&conf, 108 MBEDTLS_SSL_IS_SERVER, 109 MBEDTLS_SSL_TRANSPORT_STREAM, 110 MBEDTLS_SSL_PRESET_DEFAULT) != 0) { 111 goto exit; 112 } 113 114 srand(1); 115 mbedtls_ssl_conf_rng(&conf, dummy_random, &ctr_drbg); 116 117#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) 118 mbedtls_ssl_conf_ca_chain(&conf, srvcert.next, NULL); 119 if (mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey) != 0) { 120 goto exit; 121 } 122#endif 123 124 mbedtls_ssl_conf_cert_req_ca_list(&conf, 125 (options & 126 0x1) ? MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED : MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED); 127#if defined(MBEDTLS_SSL_ALPN) 128 if (options & 0x2) { 129 mbedtls_ssl_conf_alpn_protocols(&conf, alpn_list); 130 } 131#endif 132#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C) 133 if (options & 0x4) { 134 if (mbedtls_ssl_ticket_setup(&ticket_ctx, 135 dummy_random, &ctr_drbg, 136 MBEDTLS_CIPHER_AES_256_GCM, 137 86400) != 0) { 138 goto exit; 139 } 140 141 mbedtls_ssl_conf_session_tickets_cb(&conf, 142 mbedtls_ssl_ticket_write, 143 mbedtls_ssl_ticket_parse, 144 &ticket_ctx); 145 } 146#endif 147#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 148 mbedtls_ssl_conf_extended_master_secret(&conf, 149 (options & 150 0x10) ? MBEDTLS_SSL_EXTENDED_MS_DISABLED : MBEDTLS_SSL_EXTENDED_MS_ENABLED); 151#endif 152#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 153 mbedtls_ssl_conf_encrypt_then_mac(&conf, 154 (options & 155 0x20) ? MBEDTLS_SSL_ETM_ENABLED : MBEDTLS_SSL_ETM_DISABLED); 156#endif 157#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 158 if (options & 0x40) { 159 mbedtls_ssl_conf_psk(&conf, psk, sizeof(psk), 160 (const unsigned char *) psk_id, sizeof(psk_id) - 1); 161 } 162#endif 163#if defined(MBEDTLS_SSL_RENEGOTIATION) 164 mbedtls_ssl_conf_renegotiation(&conf, 165 (options & 166 0x80) ? MBEDTLS_SSL_RENEGOTIATION_ENABLED : MBEDTLS_SSL_RENEGOTIATION_DISABLED); 167#endif 168 169 if (mbedtls_ssl_setup(&ssl, &conf) != 0) { 170 goto exit; 171 } 172 173 biomemfuzz.Data = Data; 174 biomemfuzz.Size = Size-1; 175 biomemfuzz.Offset = 0; 176 mbedtls_ssl_set_bio(&ssl, &biomemfuzz, dummy_send, fuzz_recv, NULL); 177 178 mbedtls_ssl_session_reset(&ssl); 179 ret = mbedtls_ssl_handshake(&ssl); 180 if (ret == 0) { 181 //keep reading data from server until the end 182 do { 183 len = sizeof(buf) - 1; 184 ret = mbedtls_ssl_read(&ssl, buf, len); 185 186 if (ret == MBEDTLS_ERR_SSL_WANT_READ) { 187 continue; 188 } else if (ret <= 0) { 189 //EOF or error 190 break; 191 } 192 } while (1); 193 } 194 195exit: 196#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C) 197 mbedtls_ssl_ticket_free(&ticket_ctx); 198#endif 199 mbedtls_entropy_free(&entropy); 200 mbedtls_ctr_drbg_free(&ctr_drbg); 201 mbedtls_ssl_config_free(&conf); 202#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) 203 mbedtls_x509_crt_free(&srvcert); 204 mbedtls_pk_free(&pkey); 205#endif 206 mbedtls_ssl_free(&ssl); 207#if defined(MBEDTLS_USE_PSA_CRYPTO) 208 mbedtls_psa_crypto_free(); 209#endif 210#else 211 (void) Data; 212 (void) Size; 213#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ 214 215 return 0; 216} 217