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