From 723335243276393bfb33f97cfb13454fbf421637 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 3 May 2018 16:40:24 +0200 Subject: [PATCH 01/36] Fuzz testing Fuzz targets are x509 crt csr and crl parsing as well as private and public key parsing and client and server communication Fuzz targets for DTLS Simple corpus with valid DTLS connection Deterministic behavior for fuzzing, ie no timestamps --- tests/CMakeLists.txt | 2 + tests/fuzz/CMakeLists.txt | 38 +++++ tests/fuzz/corpuses/client | Bin 0 -> 4037 bytes tests/fuzz/corpuses/dtlsclient | Bin 0 -> 4058 bytes tests/fuzz/corpuses/dtlsserver | Bin 0 -> 1189 bytes tests/fuzz/corpuses/server | Bin 0 -> 675 bytes tests/fuzz/fuzz_client.c | 227 +++++++++++++++++++++++++++ tests/fuzz/fuzz_client.options | 2 + tests/fuzz/fuzz_dtlsclient.c | 185 ++++++++++++++++++++++ tests/fuzz/fuzz_dtlsclient.options | 2 + tests/fuzz/fuzz_dtlsserver.c | 209 +++++++++++++++++++++++++ tests/fuzz/fuzz_dtlsserver.options | 2 + tests/fuzz/fuzz_privkey.c | 64 ++++++++ tests/fuzz/fuzz_privkey.options | 2 + tests/fuzz/fuzz_pubkey.c | 57 +++++++ tests/fuzz/fuzz_pubkey.options | 2 + tests/fuzz/fuzz_server.c | 240 +++++++++++++++++++++++++++++ tests/fuzz/fuzz_server.options | 2 + tests/fuzz/fuzz_x509crl.c | 22 +++ tests/fuzz/fuzz_x509crl.options | 2 + tests/fuzz/fuzz_x509crt.c | 22 +++ tests/fuzz/fuzz_x509crt.options | 2 + tests/fuzz/fuzz_x509csr.c | 22 +++ tests/fuzz/fuzz_x509csr.options | 2 + tests/fuzz/onefile.c | 50 ++++++ 25 files changed, 1156 insertions(+) create mode 100644 tests/fuzz/CMakeLists.txt create mode 100644 tests/fuzz/corpuses/client create mode 100644 tests/fuzz/corpuses/dtlsclient create mode 100644 tests/fuzz/corpuses/dtlsserver create mode 100644 tests/fuzz/corpuses/server create mode 100644 tests/fuzz/fuzz_client.c create mode 100644 tests/fuzz/fuzz_client.options create mode 100644 tests/fuzz/fuzz_dtlsclient.c create mode 100644 tests/fuzz/fuzz_dtlsclient.options create mode 100644 tests/fuzz/fuzz_dtlsserver.c create mode 100644 tests/fuzz/fuzz_dtlsserver.options create mode 100644 tests/fuzz/fuzz_privkey.c create mode 100644 tests/fuzz/fuzz_privkey.options create mode 100644 tests/fuzz/fuzz_pubkey.c create mode 100644 tests/fuzz/fuzz_pubkey.options create mode 100644 tests/fuzz/fuzz_server.c create mode 100644 tests/fuzz/fuzz_server.options create mode 100644 tests/fuzz/fuzz_x509crl.c create mode 100644 tests/fuzz/fuzz_x509crl.options create mode 100644 tests/fuzz/fuzz_x509crt.c create mode 100644 tests/fuzz/fuzz_x509crt.options create mode 100644 tests/fuzz/fuzz_x509csr.c create mode 100644 tests/fuzz/fuzz_x509csr.options create mode 100644 tests/fuzz/onefile.c diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ecf6f34b2f..d060255bdb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -77,3 +77,5 @@ if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) link_to_source(scripts) link_to_source(ssl-opt.sh) endif() + +add_subdirectory(fuzz) diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt new file mode 100644 index 0000000000..1392f63ca3 --- /dev/null +++ b/tests/fuzz/CMakeLists.txt @@ -0,0 +1,38 @@ +set(libs + mbedtls +) + +if(USE_PKCS11_HELPER_LIBRARY) + set(libs ${libs} pkcs11-helper) +endif(USE_PKCS11_HELPER_LIBRARY) + +if(ENABLE_ZLIB_SUPPORT) + set(libs ${libs} ${ZLIB_LIBRARIES}) +endif(ENABLE_ZLIB_SUPPORT) + +add_executable(fuzz_x509csr fuzz_x509csr.c onefile.c) +target_link_libraries(fuzz_x509csr ${libs}) + +add_executable(fuzz_x509crl fuzz_x509crl.c onefile.c) +target_link_libraries(fuzz_x509crl ${libs}) + +add_executable(fuzz_x509crt fuzz_x509crt.c onefile.c) +target_link_libraries(fuzz_x509crt ${libs}) + +add_executable(fuzz_privkey fuzz_privkey.c onefile.c) +target_link_libraries(fuzz_privkey ${libs}) + +add_executable(fuzz_pubkey fuzz_pubkey.c onefile.c) +target_link_libraries(fuzz_pubkey ${libs}) + +add_executable(fuzz_client fuzz_client.c onefile.c) +target_link_libraries(fuzz_client ${libs}) + +add_executable(fuzz_server fuzz_server.c onefile.c) +target_link_libraries(fuzz_server ${libs}) + +add_executable(fuzz_dtlsclient fuzz_dtlsclient.c onefile.c) +target_link_libraries(fuzz_dtlsclient ${libs}) + +add_executable(fuzz_dtlsserver fuzz_dtlsserver.c onefile.c) +target_link_libraries(fuzz_dtlsserver ${libs}) diff --git a/tests/fuzz/corpuses/client b/tests/fuzz/corpuses/client new file mode 100644 index 0000000000000000000000000000000000000000..48d0a67c8f36ace60ccf4013a5b985207703ed80 GIT binary patch literal 4037 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 B`4|8I literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpuses/dtlsserver b/tests/fuzz/corpuses/dtlsserver new file mode 100644 index 0000000000000000000000000000000000000000..7a7a117900781be46a5b985b275d625ef98b8c96 GIT binary patch literal 1189 zcmeHGYfQ~y9Dd&OKed!oraGZql5k2FMY=IQC>?!Zlr0-G3@h3y2VpKLUDct`kxFiL zI@MfO(=3nsd|;W|T-LITvM_BKnvOSJKKta8=gaT;-S+<8-}AoOek+C`jthv~K}Y2F z|JrnKOX_l~zFYUOxwfaTBWlmBmEYYvKNJ`e{MQFpJTL*mma`a$3f8fL(>N1}w5JQg z*ub+q%slR8DtF)xvgykJl+(g;dT|CeaTJ{q%z9Qai@Dsx6dKTi#kAvCXi>|H48;|O zz(^xc@dRsO<^|5fWzIzri+G$SnmGrBIL*_TkGTw@51r`G>9pY)?gnv)1>D6PZbuo* z5QzZJrjCyEqc_#8WICF$i22;fY^K4U8Y-wm6H0iDrLdq8#XQQBIEEUYM*|92$P(6| zn&(iDd>&yjtC0t*021Wh95EUgm6W`GUDD>{)HG=1O$PAg6%QydpL{k!aD&v!y&pqjC5YuX;$QKk01-+D78Z(T-D;xh4H!ha&+uK~#s{3VYWqz0{Yv%U$#2?KR;OS5)KIu)%fV2}8-ZCHmf{)6Q&l z`Wj@ezdduJ@=~YnePn8R7weHT)un%UJOx5%rT6EB$pHh0nOm69Ps&R#Ee{{vl#uQa z6*IZLyl+*;oW>RLapA2+_O`~3lWiL}zj7OC7VsQu7N0X?t_LSahlF-py54Bl1}u2i nv9Hu>xftj=Qmv9dVDL~?`zO!puqtOwgrV+z*#6Zm+cJIwp9Z@o literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpuses/server b/tests/fuzz/corpuses/server new file mode 100644 index 0000000000000000000000000000000000000000..fbeb019f200a63d8f40815551f07375c0265c4e6 GIT binary patch literal 675 zcmXYsSxD4z6ot>v|0wF@SUPGhQKaUUySADrl!Z=#p*;u%p=F^VsJTZNxsH>2mbq6h zmlop{>)-gi7Q%?T>4Qdgvyo18MFLH!#(wtlE(@sT6{av9Pf$n? zdZU3|Y@j1u5Kj|Y!k;~CVLpqQ!(^sm1V?C03s|F*ZQO?e?m;=rd51OZgr2S3i+%>8 zjAgvZTIv~qQq;2^hY(0Vy3?Fq+(kn+GaJNp>X^wQUPc}35Cm`f(v2#5(wPc2F$=>8 zWeGD_$W)lpj1syrglbmuHo7o~Dpv3oD$&9F=!K4@tY!z=c@I4(;SE-?9a^jlAO?U6 zn*fu@m+YzHf-VF?Q; zAp>#)xd$BOC`l;Z4CLo2#Hpj^o^wkFhE&cUp02V=<2=7GYU}9tu_W)$FORrBjoE{d z@Wt|V|5sB7iyyTXrWuz{)&{){i%w8x&Gqk?Y#D=fhU$0nHJw{-UFpi1h`zPFOnbA} zvk!%PbXkXIZ=6*~O#{2OX(K-Ys literal 0 HcmV?d00001 diff --git a/tests/fuzz/fuzz_client.c b/tests/fuzz/fuzz_client.c new file mode 100644 index 0000000000..aee9946d9b --- /dev/null +++ b/tests/fuzz/fuzz_client.c @@ -0,0 +1,227 @@ +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/certs.h" +#include +#include +#include +#include + + +static bool initialized = 0; +#if defined(MBEDTLS_X509_CRT_PARSE_C) +static mbedtls_x509_crt cacert; +#endif +const char *alpn_list[3]; + + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +const unsigned char psk[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +}; +const char psk_id[] = "Client_identity"; +#endif + +const char *pers = "fuzz_client"; + + +typedef struct fuzzBufferOffset +{ + const uint8_t *Data; + size_t Size; + size_t Offset; +} fuzzBufferOffset_t; + +static int dummy_send( void *ctx, const unsigned char *buf, size_t len ) +{ + //silence warning about unused parameter + (void) ctx; + (void) buf; + + //pretends we wrote everything ok + return( len ); +} + +static int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) +{ + //reads from the buffer from fuzzer + fuzzBufferOffset_t * biomemfuzz = (fuzzBufferOffset_t *) ctx; + + if (biomemfuzz->Offset == biomemfuzz->Size) { + //EOF + return (0); + } + if (len + biomemfuzz->Offset > biomemfuzz->Size) { + //do not overflow + len = biomemfuzz->Size - biomemfuzz->Offset; + } + memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); + biomemfuzz->Offset += len; + return( len ); +} + +static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) +{ + int ret; + size_t i; + + //use mbedtls_ctr_drbg_random to find bugs in it + ret = mbedtls_ctr_drbg_random(p_rng, output, output_len); + for (i=0; i +#include +#include +#include +#include "mbedtls/ssl.h" +#if defined(MBEDTLS_SSL_PROTO_DTLS) +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/certs.h" +#include "mbedtls/timing.h" + + +static bool initialized = 0; +#if defined(MBEDTLS_X509_CRT_PARSE_C) +static mbedtls_x509_crt cacert; +#endif + + +const char *pers = "fuzz_dtlsclient"; + + +typedef struct fuzzBufferOffset +{ + const uint8_t *Data; + size_t Size; + size_t Offset; +} fuzzBufferOffset_t; + +static int dummy_send( void *ctx, const unsigned char *buf, size_t len ) +{ + //silence warning about unused parameter + (void) ctx; + (void) buf; + + //pretends we wrote everything ok + return( len ); +} + +static int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) +{ + //reads from the buffer from fuzzer + fuzzBufferOffset_t * biomemfuzz = (fuzzBufferOffset_t *) ctx; + + if (biomemfuzz->Offset == biomemfuzz->Size) { + //EOF + return (0); + } + if (len + biomemfuzz->Offset > biomemfuzz->Size) { + //do not overflow + len = biomemfuzz->Size - biomemfuzz->Offset; + } + memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); + biomemfuzz->Offset += len; + return( len ); +} + +static int fuzz_recv_timeout( void *ctx, unsigned char *buf, size_t len, + uint32_t timeout ) +{ + (void) timeout; + + return fuzz_recv(ctx, buf, len); +} + +static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) +{ + int ret; + size_t i; + + //use mbedtls_ctr_drbg_random to find bugs in it + ret = mbedtls_ctr_drbg_random(p_rng, output, output_len); + for (i=0; i +#include +#include +#include +#include "mbedtls/ssl.h" +#if defined(MBEDTLS_SSL_PROTO_DTLS) +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/certs.h" +#include "mbedtls/timing.h" +#include "mbedtls/ssl_cookie.h" + + +const char *pers = "fuzz_dtlsserver"; +const unsigned char client_ip[4] = {0x7F, 0, 0, 1}; +static bool initialized = 0; +#if defined(MBEDTLS_X509_CRT_PARSE_C) +static mbedtls_x509_crt srvcert; +static mbedtls_pk_context pkey; +#endif + +typedef struct fuzzBufferOffset +{ + const uint8_t *Data; + size_t Size; + size_t Offset; +} fuzzBufferOffset_t; + + +static int dummy_send( void *ctx, const unsigned char *buf, size_t len ) +{ + //silence warning about unused parameter + (void) ctx; + (void) buf; + + //pretends we wrote everything ok + return( len ); +} + +static int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) +{ + //reads from the buffer from fuzzer + fuzzBufferOffset_t * biomemfuzz = (fuzzBufferOffset_t *) ctx; + + if (biomemfuzz->Offset == biomemfuzz->Size) { + //EOF + return (0); + } + if (len + biomemfuzz->Offset > biomemfuzz->Size) { + //do not overflow + len = biomemfuzz->Size - biomemfuzz->Offset; + } + memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); + biomemfuzz->Offset += len; + return( len ); +} + +static int fuzz_recv_timeout( void *ctx, unsigned char *buf, size_t len, + uint32_t timeout ) +{ + (void) timeout; + + return fuzz_recv(ctx, buf, len); +} + +static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) +{ + int ret; + size_t i; + + //use mbedtls_ctr_drbg_random to find bugs in it + ret = mbedtls_ctr_drbg_random(p_rng, output, output_len); + for (i=0; i +#include "mbedtls/pk.h" + +//4 Kb should be enough for every bug ;-) +#define MAX_LEN 0x1000 + + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +#ifdef MBEDTLS_PK_PARSE_C + int ret; + mbedtls_pk_context pk; + + if (Size > MAX_LEN) { + //only work on small inputs + Size = MAX_LEN; + } + + mbedtls_pk_init( &pk ); + ret = mbedtls_pk_parse_key( &pk, Data, Size, NULL, 0 ); + if (ret == 0) { +#if defined(MBEDTLS_RSA_C) + if( mbedtls_pk_get_type( &pk ) == MBEDTLS_PK_RSA ) + { + mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; + mbedtls_rsa_context *rsa; + + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP ); + mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP ); + + rsa = mbedtls_pk_rsa( pk ); + mbedtls_rsa_export( rsa, &N, &P, &Q, &D, &E ); + mbedtls_rsa_export_crt( rsa, &DP, &DQ, &QP ); + + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP ); + mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP ); + } + else +#endif +#if defined(MBEDTLS_ECP_C) + if( mbedtls_pk_get_type( &pk ) == MBEDTLS_PK_ECKEY ) + { + mbedtls_ecp_keypair *ecp; + + ecp = mbedtls_pk_ec( pk ); + if (ecp) { + ret = 0; + } + } + else +#endif + { + ret = 0; + } + } + mbedtls_pk_free( &pk ); +#else + (void) Data; + (void) Size; +#endif //MBEDTLS_PK_PARSE_C + + return 0; +} diff --git a/tests/fuzz/fuzz_privkey.options b/tests/fuzz/fuzz_privkey.options new file mode 100644 index 0000000000..0824b19fab --- /dev/null +++ b/tests/fuzz/fuzz_privkey.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 65535 diff --git a/tests/fuzz/fuzz_pubkey.c b/tests/fuzz/fuzz_pubkey.c new file mode 100644 index 0000000000..df42f7d53b --- /dev/null +++ b/tests/fuzz/fuzz_pubkey.c @@ -0,0 +1,57 @@ +#include +#include "mbedtls/pk.h" + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +#ifdef MBEDTLS_PK_PARSE_C + int ret; + mbedtls_pk_context pk; + + mbedtls_pk_init( &pk ); + ret = mbedtls_pk_parse_public_key( &pk, Data, Size ); + if (ret == 0) { +#if defined(MBEDTLS_RSA_C) + if( mbedtls_pk_get_type( &pk ) == MBEDTLS_PK_RSA ) + { + mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; + mbedtls_rsa_context *rsa; + + mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP ); + mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP ); + + rsa = mbedtls_pk_rsa( pk ); + ret = mbedtls_rsa_export( rsa, &N, &P, &Q, &D, &E ); + ret = mbedtls_rsa_export_crt( rsa, &DP, &DQ, &QP ); + + mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP ); + mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP ); + + } + else +#endif +#if defined(MBEDTLS_ECP_C) + if( mbedtls_pk_get_type( &pk ) == MBEDTLS_PK_ECKEY ) + { + mbedtls_ecp_keypair *ecp; + + ecp = mbedtls_pk_ec( pk ); + //dummy use of value + if (ecp) { + ret = 0; + } + } + else +#endif + { + ret = 0; + } + } + mbedtls_pk_free( &pk ); +#else + (void) Data; + (void) Size; +#endif //MBEDTLS_PK_PARSE_C + + return 0; +} diff --git a/tests/fuzz/fuzz_pubkey.options b/tests/fuzz/fuzz_pubkey.options new file mode 100644 index 0000000000..0824b19fab --- /dev/null +++ b/tests/fuzz/fuzz_pubkey.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 65535 diff --git a/tests/fuzz/fuzz_server.c b/tests/fuzz/fuzz_server.c new file mode 100644 index 0000000000..5a9510dda9 --- /dev/null +++ b/tests/fuzz/fuzz_server.c @@ -0,0 +1,240 @@ +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/certs.h" +#include "mbedtls/ssl_ticket.h" +#include +#include +#include +#include + + +const char *pers = "fuzz_server"; +static bool initialized = 0; +#if defined(MBEDTLS_X509_CRT_PARSE_C) +static mbedtls_x509_crt srvcert; +static mbedtls_pk_context pkey; +#endif +const char *alpn_list[3]; + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +const unsigned char psk[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +}; +const char psk_id[] = "Client_identity"; +#endif + + +typedef struct fuzzBufferOffset +{ + const uint8_t *Data; + size_t Size; + size_t Offset; +} fuzzBufferOffset_t; + + +static int dummy_send( void *ctx, const unsigned char *buf, size_t len ) +{ + //silence warning about unused parameter + (void) ctx; + (void) buf; + + //pretends we wrote everything ok + return( len ); +} + +static int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) +{ + //reads from the buffer from fuzzer + fuzzBufferOffset_t * biomemfuzz = (fuzzBufferOffset_t *) ctx; + + if (biomemfuzz->Offset == biomemfuzz->Size) { + //EOF + return (0); + } + if (len + biomemfuzz->Offset > biomemfuzz->Size) { + //do not overflow + len = biomemfuzz->Size - biomemfuzz->Offset; + } + memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); + biomemfuzz->Offset += len; + return( len ); +} + +static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) +{ + int ret; + size_t i; + + //use mbedtls_ctr_drbg_random to find bugs in it + ret = mbedtls_ctr_drbg_random(p_rng, output, output_len); + for (i=0; i +#include "mbedtls/x509_crl.h" + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +#ifdef MBEDTLS_X509_CRL_PARSE_C + int ret; + mbedtls_x509_crl crl; + unsigned char buf[4096]; + + mbedtls_x509_crl_init( &crl ); + ret = mbedtls_x509_crl_parse( &crl, Data, Size ); + if (ret == 0) { + ret = mbedtls_x509_crl_info( (char *) buf, sizeof( buf ) - 1, " ", &crl ); + } + mbedtls_x509_crl_free( &crl ); +#else + (void) Data; + (void) Size; +#endif + + return 0; +} diff --git a/tests/fuzz/fuzz_x509crl.options b/tests/fuzz/fuzz_x509crl.options new file mode 100644 index 0000000000..0824b19fab --- /dev/null +++ b/tests/fuzz/fuzz_x509crl.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 65535 diff --git a/tests/fuzz/fuzz_x509crt.c b/tests/fuzz/fuzz_x509crt.c new file mode 100644 index 0000000000..8f593a1414 --- /dev/null +++ b/tests/fuzz/fuzz_x509crt.c @@ -0,0 +1,22 @@ +#include +#include "mbedtls/x509_crt.h" + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +#ifdef MBEDTLS_X509_CRT_PARSE_C + int ret; + mbedtls_x509_crt crt; + unsigned char buf[4096]; + + mbedtls_x509_crt_init( &crt ); + ret = mbedtls_x509_crt_parse( &crt, Data, Size ); + if (ret == 0) { + ret = mbedtls_x509_crt_info( (char *) buf, sizeof( buf ) - 1, " ", &crt ); + } + mbedtls_x509_crt_free( &crt ); +#else + (void) Data; + (void) Size; +#endif + + return 0; +} diff --git a/tests/fuzz/fuzz_x509crt.options b/tests/fuzz/fuzz_x509crt.options new file mode 100644 index 0000000000..0824b19fab --- /dev/null +++ b/tests/fuzz/fuzz_x509crt.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 65535 diff --git a/tests/fuzz/fuzz_x509csr.c b/tests/fuzz/fuzz_x509csr.c new file mode 100644 index 0000000000..3cf28a6fa7 --- /dev/null +++ b/tests/fuzz/fuzz_x509csr.c @@ -0,0 +1,22 @@ +#include +#include "mbedtls/x509_csr.h" + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +#ifdef MBEDTLS_X509_CSR_PARSE_C + int ret; + mbedtls_x509_csr csr; + unsigned char buf[4096]; + + mbedtls_x509_csr_init( &csr ); + ret = mbedtls_x509_csr_parse( &csr, Data, Size ); + if (ret == 0) { + ret = mbedtls_x509_csr_info( (char *) buf, sizeof( buf ) - 1, " ", &csr ); + } + mbedtls_x509_csr_free( &csr ); +#else + (void) Data; + (void) Size; +#endif + + return 0; +} diff --git a/tests/fuzz/fuzz_x509csr.options b/tests/fuzz/fuzz_x509csr.options new file mode 100644 index 0000000000..0824b19fab --- /dev/null +++ b/tests/fuzz/fuzz_x509csr.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 65535 diff --git a/tests/fuzz/onefile.c b/tests/fuzz/onefile.c new file mode 100644 index 0000000000..caf3ca565e --- /dev/null +++ b/tests/fuzz/onefile.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); + +int main(int argc, char** argv) +{ + FILE * fp; + uint8_t *Data; + size_t Size; + + if (argc != 2) { + return 1; + } + //opens the file, get its size, and reads it into a buffer + fp = fopen(argv[1], "rb"); + if (fp == NULL) { + return 2; + } + if (fseek(fp, 0L, SEEK_END) != 0) { + fclose(fp); + return 2; + } + Size = ftell(fp); + if (Size == (size_t) -1) { + fclose(fp); + return 2; + } + if (fseek(fp, 0L, SEEK_SET) != 0) { + fclose(fp); + return 2; + } + Data = malloc(Size); + if (Data == NULL) { + fclose(fp); + return 2; + } + if (fread(Data, Size, 1, fp) != 1) { + fclose(fp); + return 2; + } + + //lauch fuzzer + LLVMFuzzerTestOneInput(Data, Size); + fclose(fp); + return 0; +} + From 9c7b698a2e79c284d2e1ad60747ab2f6dfd3c182 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 29 May 2018 17:00:39 +0200 Subject: [PATCH 02/36] Fuzz performance test without entropy --- tests/fuzz/fuzz_client.c | 6 +++--- tests/fuzz/fuzz_dtlsclient.c | 6 +++--- tests/fuzz/fuzz_dtlsserver.c | 6 +++--- tests/fuzz/fuzz_server.c | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/fuzz/fuzz_client.c b/tests/fuzz/fuzz_client.c index aee9946d9b..7860177a17 100644 --- a/tests/fuzz/fuzz_client.c +++ b/tests/fuzz/fuzz_client.c @@ -77,16 +77,16 @@ static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) static int dummy_entropy( void *data, unsigned char *output, size_t len ) { - int ret; size_t i; //use mbedtls_entropy_func to find bugs in it - ret = mbedtls_entropy_func(data, output, len); + //test performance impact of entropy + //ret = mbedtls_entropy_func(data, output, len); for (i=0; i Date: Tue, 4 Jun 2019 12:01:51 +0200 Subject: [PATCH 03/36] Removes warnings for unused parameters --- tests/fuzz/fuzz_client.c | 1 + tests/fuzz/fuzz_dtlsclient.c | 1 + tests/fuzz/fuzz_dtlsserver.c | 1 + tests/fuzz/fuzz_server.c | 1 + 4 files changed, 4 insertions(+) diff --git a/tests/fuzz/fuzz_client.c b/tests/fuzz/fuzz_client.c index 7860177a17..2f439f5996 100644 --- a/tests/fuzz/fuzz_client.c +++ b/tests/fuzz/fuzz_client.c @@ -78,6 +78,7 @@ static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) static int dummy_entropy( void *data, unsigned char *output, size_t len ) { size_t i; + (void) data; //use mbedtls_entropy_func to find bugs in it //test performance impact of entropy diff --git a/tests/fuzz/fuzz_dtlsclient.c b/tests/fuzz/fuzz_dtlsclient.c index c88b33b739..424af81117 100644 --- a/tests/fuzz/fuzz_dtlsclient.c +++ b/tests/fuzz/fuzz_dtlsclient.c @@ -79,6 +79,7 @@ static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) static int dummy_entropy( void *data, unsigned char *output, size_t len ) { size_t i; + (void) data; //use mbedtls_entropy_func to find bugs in it //test performance impact of entropy diff --git a/tests/fuzz/fuzz_dtlsserver.c b/tests/fuzz/fuzz_dtlsserver.c index 6e59a85a7c..6f31bfbe25 100644 --- a/tests/fuzz/fuzz_dtlsserver.c +++ b/tests/fuzz/fuzz_dtlsserver.c @@ -80,6 +80,7 @@ static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) static int dummy_entropy( void *data, unsigned char *output, size_t len ) { size_t i; + (void) data; //use mbedtls_entropy_func to find bugs in it //test performance impact of entropy diff --git a/tests/fuzz/fuzz_server.c b/tests/fuzz/fuzz_server.c index 770a38633c..f8882dd85b 100644 --- a/tests/fuzz/fuzz_server.c +++ b/tests/fuzz/fuzz_server.c @@ -79,6 +79,7 @@ static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) static int dummy_entropy( void *data, unsigned char *output, size_t len ) { size_t i; + (void) data; //use mbedtls_entropy_func to find bugs in it //test performance impact of entropy From 2b7c9a2e1afe7e51722f367746a0235c188a8613 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 4 Jun 2019 12:05:36 +0200 Subject: [PATCH 04/36] Use rand instead of srand --- tests/fuzz/fuzz_client.c | 6 +++--- tests/fuzz/fuzz_dtlsclient.c | 6 +++--- tests/fuzz/fuzz_dtlsserver.c | 6 +++--- tests/fuzz/fuzz_server.c | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/fuzz/fuzz_client.c b/tests/fuzz/fuzz_client.c index 2f439f5996..b9cdddd0ee 100644 --- a/tests/fuzz/fuzz_client.c +++ b/tests/fuzz/fuzz_client.c @@ -70,7 +70,7 @@ static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) ret = mbedtls_ctr_drbg_random(p_rng, output, output_len); for (i=0; i Date: Tue, 4 Jun 2019 12:06:34 +0200 Subject: [PATCH 05/36] Fixes dummy leak in fuzz driver --- tests/fuzz/onefile.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/fuzz/onefile.c b/tests/fuzz/onefile.c index caf3ca565e..45c32829f6 100644 --- a/tests/fuzz/onefile.c +++ b/tests/fuzz/onefile.c @@ -38,12 +38,14 @@ int main(int argc, char** argv) return 2; } if (fread(Data, Size, 1, fp) != 1) { + free(Data); fclose(fp); return 2; } //lauch fuzzer LLVMFuzzerTestOneInput(Data, Size); + free(Data); fclose(fp); return 0; } From dbc0db9449de1661917ce68d1debe73314131757 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Mon, 28 May 2018 14:27:53 +0200 Subject: [PATCH 06/36] include bignum.h from x509_crt.h --- include/mbedtls/x509_crt.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index cd3be09e07..6983d60e82 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -32,6 +32,7 @@ #include "x509.h" #include "x509_crl.h" +#include "bignum.h" /** * \addtogroup x509_module From 08633825c0c4924aff342d5ce07373cfbc8f7426 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 4 Jun 2019 14:03:06 +0200 Subject: [PATCH 07/36] Using custom time --- tests/fuzz/CMakeLists.txt | 8 ++++---- tests/fuzz/common.c | 14 ++++++++++++++ tests/fuzz/common.h | 4 ++++ tests/fuzz/fuzz_client.c | 4 +++- tests/fuzz/fuzz_dtlsclient.c | 3 +++ tests/fuzz/fuzz_dtlsserver.c | 3 +++ tests/fuzz/fuzz_server.c | 3 +++ 7 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 tests/fuzz/common.c create mode 100644 tests/fuzz/common.h diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt index 1392f63ca3..4f37efa9fb 100644 --- a/tests/fuzz/CMakeLists.txt +++ b/tests/fuzz/CMakeLists.txt @@ -25,14 +25,14 @@ target_link_libraries(fuzz_privkey ${libs}) add_executable(fuzz_pubkey fuzz_pubkey.c onefile.c) target_link_libraries(fuzz_pubkey ${libs}) -add_executable(fuzz_client fuzz_client.c onefile.c) +add_executable(fuzz_client fuzz_client.c common.c onefile.c) target_link_libraries(fuzz_client ${libs}) -add_executable(fuzz_server fuzz_server.c onefile.c) +add_executable(fuzz_server fuzz_server.c common.c onefile.c) target_link_libraries(fuzz_server ${libs}) -add_executable(fuzz_dtlsclient fuzz_dtlsclient.c onefile.c) +add_executable(fuzz_dtlsclient fuzz_dtlsclient.c common.c onefile.c) target_link_libraries(fuzz_dtlsclient ${libs}) -add_executable(fuzz_dtlsserver fuzz_dtlsserver.c onefile.c) +add_executable(fuzz_dtlsserver fuzz_dtlsserver.c common.c onefile.c) target_link_libraries(fuzz_dtlsserver ${libs}) diff --git a/tests/fuzz/common.c b/tests/fuzz/common.c new file mode 100644 index 0000000000..450f74bba0 --- /dev/null +++ b/tests/fuzz/common.c @@ -0,0 +1,14 @@ +#include "common.h" + +mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ) { + (void) time; + return 0x5af2a056; +} + +void dummy_init() { +#if defined(MBEDTLS_PLATFORM_TIME_ALT) + mbedtls_platform_set_time( dummy_constant_time ); +#else + fprintf(stderr, "Warning: fuzzing without constant time\n"); +#endif +} diff --git a/tests/fuzz/common.h b/tests/fuzz/common.h new file mode 100644 index 0000000000..03dc2a4f4f --- /dev/null +++ b/tests/fuzz/common.h @@ -0,0 +1,4 @@ +#include "mbedtls/platform_time.h" + +mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ); +void dummy_init(); diff --git a/tests/fuzz/fuzz_client.c b/tests/fuzz/fuzz_client.c index b9cdddd0ee..783cd48433 100644 --- a/tests/fuzz/fuzz_client.c +++ b/tests/fuzz/fuzz_client.c @@ -2,6 +2,7 @@ #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" #include "mbedtls/certs.h" +#include "common.h" #include #include #include @@ -90,7 +91,6 @@ static int dummy_entropy( void *data, unsigned char *output, size_t len ) return( 0 ); } - int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { int ret; size_t len; @@ -114,6 +114,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { alpn_list[1] = "fuzzalpn"; alpn_list[2] = NULL; + dummy_init(); + initialized = 1; } diff --git a/tests/fuzz/fuzz_dtlsclient.c b/tests/fuzz/fuzz_dtlsclient.c index 55cd43b214..4215313f14 100644 --- a/tests/fuzz/fuzz_dtlsclient.c +++ b/tests/fuzz/fuzz_dtlsclient.c @@ -2,6 +2,7 @@ #include #include #include +#include "common.h" #include "mbedtls/ssl.h" #if defined(MBEDTLS_SSL_PROTO_DTLS) #include "mbedtls/entropy.h" @@ -113,6 +114,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { mbedtls_test_cas_pem_len ) != 0) return 1; #endif + dummy_init(); + initialized = 1; } diff --git a/tests/fuzz/fuzz_dtlsserver.c b/tests/fuzz/fuzz_dtlsserver.c index d50b0adbed..e534b0efff 100644 --- a/tests/fuzz/fuzz_dtlsserver.c +++ b/tests/fuzz/fuzz_dtlsserver.c @@ -2,6 +2,7 @@ #include #include #include +#include "common.h" #include "mbedtls/ssl.h" #if defined(MBEDTLS_SSL_PROTO_DTLS) #include "mbedtls/entropy.h" @@ -120,6 +121,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { mbedtls_test_srv_key_len, NULL, 0 ) != 0) return 1; #endif + dummy_init(); + initialized = 1; } mbedtls_ssl_init( &ssl ); diff --git a/tests/fuzz/fuzz_server.c b/tests/fuzz/fuzz_server.c index 8d10c59693..0a96028f6d 100644 --- a/tests/fuzz/fuzz_server.c +++ b/tests/fuzz/fuzz_server.c @@ -3,6 +3,7 @@ #include "mbedtls/ctr_drbg.h" #include "mbedtls/certs.h" #include "mbedtls/ssl_ticket.h" +#include "common.h" #include #include #include @@ -131,6 +132,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { alpn_list[1] = "fuzzalpn"; alpn_list[2] = NULL; + dummy_init(); + initialized = 1; } mbedtls_ssl_init( &ssl ); From 499c735d5e7fbe9998eee4209d22d23b42106853 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 4 Jun 2019 14:14:33 +0200 Subject: [PATCH 08/36] Factoring code --- tests/fuzz/common.c | 75 +++++++++++++++++++++++++++++++++++- tests/fuzz/common.h | 15 ++++++++ tests/fuzz/fuzz_client.c | 64 ------------------------------ tests/fuzz/fuzz_dtlsclient.c | 73 ----------------------------------- tests/fuzz/fuzz_dtlsserver.c | 73 ----------------------------------- tests/fuzz/fuzz_server.c | 66 ------------------------------- 6 files changed, 88 insertions(+), 278 deletions(-) diff --git a/tests/fuzz/common.c b/tests/fuzz/common.c index 450f74bba0..a9d3d3b86f 100644 --- a/tests/fuzz/common.c +++ b/tests/fuzz/common.c @@ -1,14 +1,85 @@ #include "common.h" +#include +#include +#include +#include "mbedtls/ctr_drbg.h" -mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ) { +mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ) +{ (void) time; return 0x5af2a056; } -void dummy_init() { +void dummy_init() +{ #if defined(MBEDTLS_PLATFORM_TIME_ALT) mbedtls_platform_set_time( dummy_constant_time ); #else fprintf(stderr, "Warning: fuzzing without constant time\n"); #endif } + +int dummy_send( void *ctx, const unsigned char *buf, size_t len ) +{ + //silence warning about unused parameter + (void) ctx; + (void) buf; + + //pretends we wrote everything ok + return( len ); +} + +int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) +{ + //reads from the buffer from fuzzer + fuzzBufferOffset_t * biomemfuzz = (fuzzBufferOffset_t *) ctx; + + if (biomemfuzz->Offset == biomemfuzz->Size) { + //EOF + return (0); + } + if (len + biomemfuzz->Offset > biomemfuzz->Size) { + //do not overflow + len = biomemfuzz->Size - biomemfuzz->Offset; + } + memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); + biomemfuzz->Offset += len; + return( len ); +} + +int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) +{ + int ret; + size_t i; + + //use mbedtls_ctr_drbg_random to find bugs in it + ret = mbedtls_ctr_drbg_random(p_rng, output, output_len); + for (i=0; i + +typedef struct fuzzBufferOffset +{ + const uint8_t *Data; + size_t Size; + size_t Offset; +} fuzzBufferOffset_t; mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ); void dummy_init(); + +int dummy_send( void *ctx, const unsigned char *buf, size_t len ); +int fuzz_recv( void *ctx, unsigned char *buf, size_t len ); +int dummy_random( void *p_rng, unsigned char *output, size_t output_len ); +int dummy_entropy( void *data, unsigned char *output, size_t len ); +int fuzz_recv_timeout( void *ctx, unsigned char *buf, size_t len, + uint32_t timeout ); diff --git a/tests/fuzz/fuzz_client.c b/tests/fuzz/fuzz_client.c index 783cd48433..bb3d6e6566 100644 --- a/tests/fuzz/fuzz_client.c +++ b/tests/fuzz/fuzz_client.c @@ -27,70 +27,6 @@ const char psk_id[] = "Client_identity"; const char *pers = "fuzz_client"; -typedef struct fuzzBufferOffset -{ - const uint8_t *Data; - size_t Size; - size_t Offset; -} fuzzBufferOffset_t; - -static int dummy_send( void *ctx, const unsigned char *buf, size_t len ) -{ - //silence warning about unused parameter - (void) ctx; - (void) buf; - - //pretends we wrote everything ok - return( len ); -} - -static int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) -{ - //reads from the buffer from fuzzer - fuzzBufferOffset_t * biomemfuzz = (fuzzBufferOffset_t *) ctx; - - if (biomemfuzz->Offset == biomemfuzz->Size) { - //EOF - return (0); - } - if (len + biomemfuzz->Offset > biomemfuzz->Size) { - //do not overflow - len = biomemfuzz->Size - biomemfuzz->Offset; - } - memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); - biomemfuzz->Offset += len; - return( len ); -} - -static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) -{ - int ret; - size_t i; - - //use mbedtls_ctr_drbg_random to find bugs in it - ret = mbedtls_ctr_drbg_random(p_rng, output, output_len); - for (i=0; iOffset == biomemfuzz->Size) { - //EOF - return (0); - } - if (len + biomemfuzz->Offset > biomemfuzz->Size) { - //do not overflow - len = biomemfuzz->Size - biomemfuzz->Offset; - } - memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); - biomemfuzz->Offset += len; - return( len ); -} - -static int fuzz_recv_timeout( void *ctx, unsigned char *buf, size_t len, - uint32_t timeout ) -{ - (void) timeout; - - return fuzz_recv(ctx, buf, len); -} - -static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) -{ - int ret; - size_t i; - - //use mbedtls_ctr_drbg_random to find bugs in it - ret = mbedtls_ctr_drbg_random(p_rng, output, output_len); - for (i=0; iOffset == biomemfuzz->Size) { - //EOF - return (0); - } - if (len + biomemfuzz->Offset > biomemfuzz->Size) { - //do not overflow - len = biomemfuzz->Size - biomemfuzz->Offset; - } - memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); - biomemfuzz->Offset += len; - return( len ); -} - -static int fuzz_recv_timeout( void *ctx, unsigned char *buf, size_t len, - uint32_t timeout ) -{ - (void) timeout; - - return fuzz_recv(ctx, buf, len); -} - -static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) -{ - int ret; - size_t i; - - //use mbedtls_ctr_drbg_random to find bugs in it - ret = mbedtls_ctr_drbg_random(p_rng, output, output_len); - for (i=0; iOffset == biomemfuzz->Size) { - //EOF - return (0); - } - if (len + biomemfuzz->Offset > biomemfuzz->Size) { - //do not overflow - len = biomemfuzz->Size - biomemfuzz->Offset; - } - memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); - biomemfuzz->Offset += len; - return( len ); -} - -static int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) -{ - int ret; - size_t i; - - //use mbedtls_ctr_drbg_random to find bugs in it - ret = mbedtls_ctr_drbg_random(p_rng, output, output_len); - for (i=0; i Date: Tue, 4 Jun 2019 14:17:41 +0200 Subject: [PATCH 09/36] Adds a ChangeLog entry --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index a461008786..da39ca23c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -103,6 +103,8 @@ Changes * Make it easier to define MBEDTLS_PARAM_FAILED as assert (which config.h suggests). #2671 * Make `make clean` clean all programs always. Fixes #1862. + * Adds fuzz targets, especially for continuous fuzzing with OSS-Fuzz. + Contributed by Philippe Antoine (Catena cyber). = mbed TLS 2.17.0 branch released 2019-03-19 From 8149627b8040ad9774350999027586e2a3f20de5 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 4 Jun 2019 14:47:58 +0200 Subject: [PATCH 10/36] Fuzz README and direct compilation --- tests/fuzz/CMakeLists.txt | 78 ++++++++++++++++++++++++++++++--------- tests/fuzz/README.md | 35 ++++++++++++++++++ 2 files changed, 95 insertions(+), 18 deletions(-) create mode 100644 tests/fuzz/README.md diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt index 4f37efa9fb..17ec3f64c1 100644 --- a/tests/fuzz/CMakeLists.txt +++ b/tests/fuzz/CMakeLists.txt @@ -10,29 +10,71 @@ if(ENABLE_ZLIB_SUPPORT) set(libs ${libs} ${ZLIB_LIBRARIES}) endif(ENABLE_ZLIB_SUPPORT) -add_executable(fuzz_x509csr fuzz_x509csr.c onefile.c) -target_link_libraries(fuzz_x509csr ${libs}) +find_library(FUZZINGENGINE_LIB FuzzingEngine) -add_executable(fuzz_x509crl fuzz_x509crl.c onefile.c) -target_link_libraries(fuzz_x509crl ${libs}) +if(NOT FUZZINGENGINE_LIB) + add_executable(fuzz_x509csr fuzz_x509csr.c onefile.c) + target_link_libraries(fuzz_x509csr ${libs}) -add_executable(fuzz_x509crt fuzz_x509crt.c onefile.c) -target_link_libraries(fuzz_x509crt ${libs}) + add_executable(fuzz_x509crl fuzz_x509crl.c onefile.c) + target_link_libraries(fuzz_x509crl ${libs}) -add_executable(fuzz_privkey fuzz_privkey.c onefile.c) -target_link_libraries(fuzz_privkey ${libs}) + add_executable(fuzz_x509crt fuzz_x509crt.c onefile.c) + target_link_libraries(fuzz_x509crt ${libs}) -add_executable(fuzz_pubkey fuzz_pubkey.c onefile.c) -target_link_libraries(fuzz_pubkey ${libs}) + add_executable(fuzz_privkey fuzz_privkey.c onefile.c) + target_link_libraries(fuzz_privkey ${libs}) -add_executable(fuzz_client fuzz_client.c common.c onefile.c) -target_link_libraries(fuzz_client ${libs}) + add_executable(fuzz_pubkey fuzz_pubkey.c onefile.c) + target_link_libraries(fuzz_pubkey ${libs}) -add_executable(fuzz_server fuzz_server.c common.c onefile.c) -target_link_libraries(fuzz_server ${libs}) + add_executable(fuzz_client fuzz_client.c common.c onefile.c) + target_link_libraries(fuzz_client ${libs}) -add_executable(fuzz_dtlsclient fuzz_dtlsclient.c common.c onefile.c) -target_link_libraries(fuzz_dtlsclient ${libs}) + add_executable(fuzz_server fuzz_server.c common.c onefile.c) + target_link_libraries(fuzz_server ${libs}) -add_executable(fuzz_dtlsserver fuzz_dtlsserver.c common.c onefile.c) -target_link_libraries(fuzz_dtlsserver ${libs}) + add_executable(fuzz_dtlsclient fuzz_dtlsclient.c common.c onefile.c) + target_link_libraries(fuzz_dtlsclient ${libs}) + + add_executable(fuzz_dtlsserver fuzz_dtlsserver.c common.c onefile.c) + target_link_libraries(fuzz_dtlsserver ${libs}) +else() + project(fuzz CXX) + + add_executable(fuzz_x509csr fuzz_x509csr.c) + target_link_libraries(fuzz_x509csr ${libs} FuzzingEngine) + SET_TARGET_PROPERTIES(fuzz_x509csr PROPERTIES LINKER_LANGUAGE CXX) + + add_executable(fuzz_x509crl fuzz_x509crl.c) + target_link_libraries(fuzz_x509crl ${libs} FuzzingEngine) + SET_TARGET_PROPERTIES(fuzz_x509crl PROPERTIES LINKER_LANGUAGE CXX) + + add_executable(fuzz_x509crt fuzz_x509crt.c) + target_link_libraries(fuzz_x509crt ${libs} FuzzingEngine) + SET_TARGET_PROPERTIES(fuzz_x509crt PROPERTIES LINKER_LANGUAGE CXX) + + add_executable(fuzz_privkey fuzz_privkey.c) + target_link_libraries(fuzz_privkey ${libs} FuzzingEngine) + SET_TARGET_PROPERTIES(fuzz_privkey PROPERTIES LINKER_LANGUAGE CXX) + + add_executable(fuzz_pubkey fuzz_pubkey.c) + target_link_libraries(fuzz_pubkey ${libs} FuzzingEngine) + SET_TARGET_PROPERTIES(fuzz_pubkey PROPERTIES LINKER_LANGUAGE CXX) + + add_executable(fuzz_client fuzz_client.c common.c) + target_link_libraries(fuzz_client ${libs} FuzzingEngine) + SET_TARGET_PROPERTIES(fuzz_client PROPERTIES LINKER_LANGUAGE CXX) + + add_executable(fuzz_server fuzz_server.c common.c) + target_link_libraries(fuzz_server ${libs} FuzzingEngine) + SET_TARGET_PROPERTIES(fuzz_server PROPERTIES LINKER_LANGUAGE CXX) + + add_executable(fuzz_dtlsclient fuzz_dtlsclient.c common.c) + target_link_libraries(fuzz_dtlsclient ${libs} FuzzingEngine) + SET_TARGET_PROPERTIES(fuzz_dtlsclient PROPERTIES LINKER_LANGUAGE CXX) + + add_executable(fuzz_dtlsserver fuzz_dtlsserver.c common.c) + target_link_libraries(fuzz_dtlsserver ${libs} FuzzingEngine) + SET_TARGET_PROPERTIES(fuzz_dtlsserver PROPERTIES LINKER_LANGUAGE CXX) +endif() diff --git a/tests/fuzz/README.md b/tests/fuzz/README.md new file mode 100644 index 0000000000..a779c29ac0 --- /dev/null +++ b/tests/fuzz/README.md @@ -0,0 +1,35 @@ +What is it ? +------ + +This directory contains fuzz targets. +Fuzz targets are simple codes using the library. +They are used with a so-called fuzz driver, which will generate inputs, try to process them with the fuzz target, and alert in case of an unwanted behavior (such as a buffer overflow for instance). + +These targets were meant to be used with oss-fuzz but can be used in other contexts. + +This code was contributed by Philippe Antoine ( Catena cyber ). + +How to run ? +------ + +To run the fuzz targets like oss-fuzz : +``` +git clone https://github.com/google/oss-fuzz +cd oss-fuzz +python infra/helper.py build_image mbedtls +python infra/helper.py build_fuzzers --sanitizer address mbedtls +python infra/helper.py run_fuzzer mbedtls fuzz_client +``` +You can use `undefined` sanitizer as well as `address` sanitizer +And you can run any of the fuzz targets like `fuzz_client` + +To run the fuzz targets without oss-fuzz, you first need to install one libFuzzingEngine (libFuzzer for instance) +Then you need to compile the code +``` +perl scripts/config.pl set MBEDTLS_PLATFORM_TIME_ALT +mkdir build +cd build +cmake .. +make +``` +Finally, you can run the targets like `./test/fuzz/fuzz_client` From 03e87d909dd7050f8d36c676842f8430ff603424 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 4 Jun 2019 19:37:52 +0200 Subject: [PATCH 11/36] Makefile support 1 --- tests/Makefile | 7 +++-- tests/fuzz/Makefile | 72 ++++++++++++++++++++++++++++++++++++++++++++ tests/fuzz/README.md | 2 +- 3 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 tests/fuzz/Makefile diff --git a/tests/Makefile b/tests/Makefile index 27ce338954..d5dd193b88 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -112,9 +112,12 @@ BINARIES := $(addsuffix $(EXEXT),$(APPS)) .SILENT: -.PHONY: all check test clean +.PHONY: all check test clean fuzz -all: $(BINARIES) +all: $(BINARIES) fuzz + +fuzz: + $(MAKE) -C fuzz $(DEP): $(MAKE) -C ../library diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile new file mode 100644 index 0000000000..f2195d1298 --- /dev/null +++ b/tests/fuzz/Makefile @@ -0,0 +1,72 @@ + +LOCAL_CFLAGS = -I../../include -D_FILE_OFFSET_BITS=64 +LOCAL_LDFLAGS = -L../../library \ + -lmbedtls$(SHARED_SUFFIX) \ + -lmbedx509$(SHARED_SUFFIX) \ + -lmbedcrypto$(SHARED_SUFFIX) + +LOCAL_LDFLAGS += -L../../crypto/library +LOCAL_CFLAGS += -I../../crypto/include +CRYPTO := ../../crypto/library/ + +ifndef SHARED +DEP=$(CRYPTO)libmbedcrypto.a ../../library/libmbedx509.a ../../library/libmbedtls.a +else +DEP=$(CRYPTO)libmbedcrypto.$(DLEXT) ../../library/libmbedx509.$(DLEXT) ../../library/libmbedtls.$(DLEXT) +endif + + +DLEXT ?= so +EXEXT= +SHARED_SUFFIX= +# python2 for POSIX since FreeBSD has only python2 as default. +PYTHON ?= python2 + +# Zlib shared library extensions: +ifdef ZLIB +LOCAL_LDFLAGS += -lz +endif + +ifdef FUZZINGENGINE +LOCAL_LDFLAGS += -lFuzzingEngine +endif + +# A test application is built for each suites/test_suite_*.data file. +# Application name is same as .data file's base name and can be +# constructed by stripping path 'suites/' and extension .data. +APPS = $(basename $(wildcard fuzz_*.c)) + +# Construct executable name by adding OS specific suffix $(EXEXT). +BINARIES := $(addsuffix $(EXEXT),$(APPS)) + +.SILENT: + +.PHONY: all check test clean + +all: $(BINARIES) + +$(DEP): + $(MAKE) -C ../../library + +C_FILES := $(addsuffix .c,$(APPS)) + +%.o: %.c + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c $< -o $@ + + +ifdef FUZZINGENGINE +$(BINARIES): %$(EXEXT): %.o common.o $(DEP) + echo " $(CC) common.o $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@" + $(CXX) common.o $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +else +$(BINARIES): %$(EXEXT): %.o common.o onefile.o $(DEP) + echo " $(CC) common.o onefile.o $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@" + $(CC) common.o onefile.o $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +endif + +clean: +ifndef WINDOWS + rm -rf $(BINARIES) *.o +else + del /Q /F *.o *.exe +endif diff --git a/tests/fuzz/README.md b/tests/fuzz/README.md index a779c29ac0..2105ece49c 100644 --- a/tests/fuzz/README.md +++ b/tests/fuzz/README.md @@ -24,7 +24,7 @@ You can use `undefined` sanitizer as well as `address` sanitizer And you can run any of the fuzz targets like `fuzz_client` To run the fuzz targets without oss-fuzz, you first need to install one libFuzzingEngine (libFuzzer for instance) -Then you need to compile the code +Then you need to compile the code with the compiler flags of the wished sanitizer ``` perl scripts/config.pl set MBEDTLS_PLATFORM_TIME_ALT mkdir build From c32fd248e3033ff78cccda9e6d6b831d15dd73f0 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 6 Jun 2019 09:12:53 +0200 Subject: [PATCH 12/36] Protecting client/server fuzz targts with ifdefs --- tests/fuzz/fuzz_client.c | 6 ++++++ tests/fuzz/fuzz_dtlsclient.c | 2 +- tests/fuzz/fuzz_dtlsserver.c | 2 +- tests/fuzz/fuzz_server.c | 6 ++++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/fuzz/fuzz_client.c b/tests/fuzz/fuzz_client.c index bb3d6e6566..f2eaa3d335 100644 --- a/tests/fuzz/fuzz_client.c +++ b/tests/fuzz/fuzz_client.c @@ -28,6 +28,7 @@ const char *pers = "fuzz_client"; int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +#ifdef MBEDTLS_SSL_CLI_C int ret; size_t len; mbedtls_ssl_context ssl; @@ -162,5 +163,10 @@ exit: mbedtls_ssl_config_free( &conf ); mbedtls_ssl_free( &ssl ); +#else + (void) Data; + (void) Size; +#endif //MBEDTLS_SSL_CLI_C + return 0; } diff --git a/tests/fuzz/fuzz_dtlsclient.c b/tests/fuzz/fuzz_dtlsclient.c index feee8cebeb..4205917c18 100644 --- a/tests/fuzz/fuzz_dtlsclient.c +++ b/tests/fuzz/fuzz_dtlsclient.c @@ -23,7 +23,7 @@ const char *pers = "fuzz_dtlsclient"; int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { -#if defined(MBEDTLS_SSL_PROTO_DTLS) +#if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_SSL_CLI_C) int ret; size_t len; mbedtls_ssl_context ssl; diff --git a/tests/fuzz/fuzz_dtlsserver.c b/tests/fuzz/fuzz_dtlsserver.c index a60ab56c2b..619661f5e2 100644 --- a/tests/fuzz/fuzz_dtlsserver.c +++ b/tests/fuzz/fuzz_dtlsserver.c @@ -22,7 +22,7 @@ static mbedtls_pk_context pkey; #endif int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { -#if defined(MBEDTLS_SSL_PROTO_DTLS) +#if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_SSL_SRV_C) int ret; size_t len; mbedtls_ssl_context ssl; diff --git a/tests/fuzz/fuzz_server.c b/tests/fuzz/fuzz_server.c index eef0002e31..0a2f3a90c7 100644 --- a/tests/fuzz/fuzz_server.c +++ b/tests/fuzz/fuzz_server.c @@ -28,6 +28,7 @@ const char psk_id[] = "Client_identity"; int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +#ifdef MBEDTLS_SSL_SRV_C int ret; size_t len; mbedtls_ssl_context ssl; @@ -174,5 +175,10 @@ exit: mbedtls_ssl_config_free( &conf ); mbedtls_ssl_free( &ssl ); +#else + (void) Data; + (void) Size; +#endif //MBEDTLS_SSL_SRV_C + return 0; } From cd6cd811f1663eef93217e308d953ae10f66b150 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 6 Jun 2019 09:22:27 +0200 Subject: [PATCH 13/36] copyediting README.md --- tests/fuzz/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/fuzz/README.md b/tests/fuzz/README.md index 2105ece49c..f208800ab8 100644 --- a/tests/fuzz/README.md +++ b/tests/fuzz/README.md @@ -1,4 +1,4 @@ -What is it ? +What is it? ------ This directory contains fuzz targets. @@ -9,10 +9,10 @@ These targets were meant to be used with oss-fuzz but can be used in other conte This code was contributed by Philippe Antoine ( Catena cyber ). -How to run ? +How to run? ------ -To run the fuzz targets like oss-fuzz : +To run the fuzz targets like oss-fuzz: ``` git clone https://github.com/google/oss-fuzz cd oss-fuzz @@ -20,11 +20,11 @@ python infra/helper.py build_image mbedtls python infra/helper.py build_fuzzers --sanitizer address mbedtls python infra/helper.py run_fuzzer mbedtls fuzz_client ``` -You can use `undefined` sanitizer as well as `address` sanitizer -And you can run any of the fuzz targets like `fuzz_client` +You can use `undefined` sanitizer as well as `address` sanitizer. +And you can run any of the fuzz targets like `fuzz_client`. -To run the fuzz targets without oss-fuzz, you first need to install one libFuzzingEngine (libFuzzer for instance) -Then you need to compile the code with the compiler flags of the wished sanitizer +To run the fuzz targets without oss-fuzz, you first need to install one libFuzzingEngine (libFuzzer for instance). +Then you need to compile the code with the compiler flags of the wished sanitizer. ``` perl scripts/config.pl set MBEDTLS_PLATFORM_TIME_ALT mkdir build @@ -32,4 +32,4 @@ cd build cmake .. make ``` -Finally, you can run the targets like `./test/fuzz/fuzz_client` +Finally, you can run the targets like `./test/fuzz/fuzz_client`. From a8210b3b98d1603f4ed64d58273f582ae9a683e8 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Fri, 7 Jun 2019 22:25:26 +0200 Subject: [PATCH 14/36] Also clean the fuzz subdirectory --- tests/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Makefile b/tests/Makefile index d5dd193b88..2ca0fd6963 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -164,6 +164,7 @@ ifneq ($(wildcard TESTS/.*),) rmdir /Q /S TESTS endif endif + $(MAKE) -C fuzz clean # Test suites caught by SKIP_TEST_SUITES are built but not executed. check: $(BINARIES) From 7fff1fb7c54081a1538396acd72357c68db3554e Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Fri, 7 Jun 2019 22:26:36 +0200 Subject: [PATCH 15/36] Ignore compiled object files and executables --- tests/fuzz/.gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/fuzz/.gitignore diff --git a/tests/fuzz/.gitignore b/tests/fuzz/.gitignore new file mode 100644 index 0000000000..6fcc004b7e --- /dev/null +++ b/tests/fuzz/.gitignore @@ -0,0 +1,10 @@ +*.o +fuzz_client +fuzz_dtlsclient +fuzz_dtlsserver +fuzz_privkey +fuzz_pubkey +fuzz_server +fuzz_x509crl +fuzz_x509crt +fuzz_x509csr From 33908e8429c302d232a1f95cedc444edccf67ae5 Mon Sep 17 00:00:00 2001 From: Ron Eldor Date: Wed, 29 May 2019 17:17:10 +0300 Subject: [PATCH 16/36] update the test script Update `mbedtls_test.py` script to work with Python 3.7. resolves #2653 --- tests/scripts/mbedtls_test.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/scripts/mbedtls_test.py b/tests/scripts/mbedtls_test.py index ac2912d4c9..7e1cebf7d6 100755 --- a/tests/scripts/mbedtls_test.py +++ b/tests/scripts/mbedtls_test.py @@ -79,8 +79,7 @@ class TestDataParser(object): split_colon_fn = lambda x: re.sub(r'\\' + split_char, split_char, x) if len(split_char) > 1: raise ValueError('Expected split character. Found string!') - out = map(split_colon_fn, re.split(r'(? Date: Mon, 3 Jun 2019 11:38:42 +0300 Subject: [PATCH 17/36] Update the test encoding to support python3 Since Python3 handles encoding differently than Python2, a change in the way the data is encoded and sent to the target is needed. 1. Change the test data to be sent as hex string 2. Convert the characters to binary bytes. This is done because the mbed tools translate the encoding differently (mbed-greentea, and mbed-htrunner) --- tests/scripts/mbedtls_test.py | 26 ++++++++---------- tests/suites/target_test.function | 45 ++++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 21 deletions(-) diff --git a/tests/scripts/mbedtls_test.py b/tests/scripts/mbedtls_test.py index 7e1cebf7d6..62c2296319 100755 --- a/tests/scripts/mbedtls_test.py +++ b/tests/scripts/mbedtls_test.py @@ -89,24 +89,20 @@ class TestDataParser(object): :param data_f: Data file object :return: """ - while True: - line = data_f.readline().strip() + for line in data_f: + line = line.strip() if not line: - break + continue # Read test name name = line # Check dependencies dependencies = [] - line = data_f.readline().strip() - if not line: - break + line = next(data_f).strip() match = re.search('depends_on:(.*)', line) if match: dependencies = [int(x) for x in match.group(1).split(':')] - line = data_f.readline().strip() - if not line: - break + line = next(data_f).strip() # Read test vectors line = line.replace('\\n', '\n') @@ -265,20 +261,20 @@ class MbedTlsTest(BaseHostTest): for typ, param in parameters: if typ == 'int' or typ == 'exp': i = int(param) - data_bytes += 'I' if typ == 'int' else 'E' + data_bytes += b'I' if typ == 'int' else b'E' self.align_32bit(data_bytes) data_bytes += self.int32_to_big_endian_bytes(i) elif typ == 'char*': param = param.strip('"') i = len(param) + 1 # + 1 for null termination - data_bytes += 'S' + data_bytes += b'S' self.align_32bit(data_bytes) data_bytes += self.int32_to_big_endian_bytes(i) - data_bytes += bytearray(list(param)) - data_bytes += '\0' # Null terminate + data_bytes += bytes(param, 'ascii') + data_bytes += b'\0' # Null terminate elif typ == 'hex': binary_data = self.hex_str_bytes(param) - data_bytes += 'H' + data_bytes += b'H' self.align_32bit(data_bytes) i = len(binary_data) data_bytes += self.int32_to_big_endian_bytes(i) @@ -313,7 +309,7 @@ class MbedTlsTest(BaseHostTest): param_bytes, length = self.test_vector_to_bytes(function_id, dependencies, args) - self.send_kv(bytes(length).decode(), bytes(param_bytes).decode()) + self.send_kv(length.hex(), param_bytes.hex()) @staticmethod def get_result(value): diff --git a/tests/suites/target_test.function b/tests/suites/target_test.function index 56abf29489..4248260b0b 100644 --- a/tests/suites/target_test.function +++ b/tests/suites/target_test.function @@ -59,10 +59,43 @@ int verify_dependencies( uint8_t count, uint8_t * dep_p ) return( DEPENDENCY_SUPPORTED ); } +/** + * \brief Receives hex string on serial interface, and converts to a byte. + * + * \param none + * + * \return unsigned int8 + */ +uint8_t receive_byte() +{ + uint8_t byte; + uint8_t c; + + c = greentea_getc(); + if( c >= '0' && c <= '9' ) + c -= '0'; + else if( c >= 'a' && c <= 'f' ) + c = ( c -'a' ) + 10; + else if( c >= 'A' && c <= 'F' ) + c = ( c - 'A' ) + 10; + + byte = c * 0x10; + + c = greentea_getc(); + if( c >= '0' && c <= '9' ) + c -= '0'; + else if( c >= 'a' && c <= 'f' ) + c = ( c -'a' ) + 10; + else if( c >= 'A' && c <= 'F' ) + c = ( c - 'A' ) + 10; + + byte += c ; + return( byte); +} /** * \brief Receives unsigned integer on serial interface. - * Integers are encoded in network order. + * Integers are encoded in network order, and sent as hex ascii string. * * \param none * @@ -71,10 +104,10 @@ int verify_dependencies( uint8_t count, uint8_t * dep_p ) uint32_t receive_uint32() { uint32_t value; - value = (uint8_t)greentea_getc() << 24; - value |= (uint8_t)greentea_getc() << 16; - value |= (uint8_t)greentea_getc() << 8; - value |= (uint8_t)greentea_getc(); + value = receive_byte() << 24; + value |= receive_byte() << 16; + value |= receive_byte() << 8; + value |= receive_byte(); return( (uint32_t)value ); } @@ -132,7 +165,7 @@ uint8_t * receive_data( uint32_t * data_len ) greentea_getc(); // read ';' received after key i.e. *data_len for( i = 0; i < *data_len; i++ ) - data[i] = greentea_getc(); + data[i] = receive_byte(); /* Read closing braces */ for( i = 0; i < 2; i++ ) From 64e45950de379602b41b078982ed135f7a3ee492 Mon Sep 17 00:00:00 2001 From: Ron Eldor Date: Mon, 3 Jun 2019 13:39:21 +0300 Subject: [PATCH 18/36] Make the script portable to both pythons Make the script work for python3 and for python2 --- tests/scripts/mbedtls_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/mbedtls_test.py b/tests/scripts/mbedtls_test.py index 62c2296319..b7b9dc0633 100755 --- a/tests/scripts/mbedtls_test.py +++ b/tests/scripts/mbedtls_test.py @@ -270,7 +270,7 @@ class MbedTlsTest(BaseHostTest): data_bytes += b'S' self.align_32bit(data_bytes) data_bytes += self.int32_to_big_endian_bytes(i) - data_bytes += bytes(param, 'ascii') + data_bytes += bytearray(param, encoding='ascii') data_bytes += b'\0' # Null terminate elif typ == 'hex': binary_data = self.hex_str_bytes(param) @@ -309,7 +309,7 @@ class MbedTlsTest(BaseHostTest): param_bytes, length = self.test_vector_to_bytes(function_id, dependencies, args) - self.send_kv(length.hex(), param_bytes.hex()) + self.send_kv(''.join('{:02x}'.format(x) for x in length), ''.join('{:02x}'.format(x) for x in param_bytes)) @staticmethod def get_result(value): From b22048942260a20049b0c02922440375af318284 Mon Sep 17 00:00:00 2001 From: Ron Eldor Date: Mon, 3 Jun 2019 16:39:59 +0300 Subject: [PATCH 19/36] Refactor get_byte function Change implementation of `get_byte()` to call `unhexify()`. --- tests/suites/target_test.function | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/tests/suites/target_test.function b/tests/suites/target_test.function index 4248260b0b..4522fbf0ce 100644 --- a/tests/suites/target_test.function +++ b/tests/suites/target_test.function @@ -69,28 +69,14 @@ int verify_dependencies( uint8_t count, uint8_t * dep_p ) uint8_t receive_byte() { uint8_t byte; - uint8_t c; + uint8_t c[3]; + char *endptr; + c[0] = greentea_getc(); + c[1] = greentea_getc(); + c[2] = '\0'; - c = greentea_getc(); - if( c >= '0' && c <= '9' ) - c -= '0'; - else if( c >= 'a' && c <= 'f' ) - c = ( c -'a' ) + 10; - else if( c >= 'A' && c <= 'F' ) - c = ( c - 'A' ) + 10; - - byte = c * 0x10; - - c = greentea_getc(); - if( c >= '0' && c <= '9' ) - c -= '0'; - else if( c >= 'a' && c <= 'f' ) - c = ( c -'a' ) + 10; - else if( c >= 'A' && c <= 'F' ) - c = ( c - 'A' ) + 10; - - byte += c ; - return( byte); + assert( unhexify( &byte, &c ) != 2 ); + return( byte ); } /** From 72662a495ce3e92fe6bad77352e80af387eb0820 Mon Sep 17 00:00:00 2001 From: Ron Eldor Date: Tue, 25 Jun 2019 14:50:20 +0300 Subject: [PATCH 20/36] Refactor receive_uint32() Call `greentea_getc()` 8 times, and then `unhexify` once, instead of calling `receive_byte()`, which inside calls `greentea_getc()` twice, for every hex digit. --- tests/suites/target_test.function | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/suites/target_test.function b/tests/suites/target_test.function index 4522fbf0ce..71675bdf14 100644 --- a/tests/suites/target_test.function +++ b/tests/suites/target_test.function @@ -75,7 +75,7 @@ uint8_t receive_byte() c[1] = greentea_getc(); c[2] = '\0'; - assert( unhexify( &byte, &c ) != 2 ); + assert( unhexify( &byte, c ) != 2 ); return( byte ); } @@ -90,10 +90,17 @@ uint8_t receive_byte() uint32_t receive_uint32() { uint32_t value; - value = receive_byte() << 24; - value |= receive_byte() << 16; - value |= receive_byte() << 8; - value |= receive_byte(); + const uint8_t c[9] = { greentea_getc(), + greentea_getc(), + greentea_getc(), + greentea_getc(), + greentea_getc(), + greentea_getc(), + greentea_getc(), + greentea_getc(), + '\0' + }; + assert( unhexify( &value, c ) != 8 ); return( (uint32_t)value ); } From cd2c127f75c808bfecc71f34108fdfc677129e76 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 25 Jun 2019 21:50:07 +0200 Subject: [PATCH 21/36] Adds LDFLAGS fsanitize=address --- tests/scripts/all.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 9d628f88cb..ca826b0b99 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1030,7 +1030,7 @@ component_test_m32_o0 () { # Build once with -O0, to compile out the i386 specific inline assembly msg "build: i386, make, gcc -O0 (ASan build)" # ~ 30s scripts/config.pl full - make CC=gcc CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address' LDFLAGS='-m32' + make CC=gcc CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address' LDFLAGS='-m32 -fsanitize=address' msg "test: i386, make, gcc -O0 (ASan build)" make test @@ -1049,7 +1049,7 @@ component_test_m32_o1 () { scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C scripts/config.pl unset MBEDTLS_MEMORY_DEBUG - make CC=gcc CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address' LDFLAGS='-m32' + make CC=gcc CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address' LDFLAGS='-m32 -fsanitize=address' msg "test: i386, make, gcc -O1 (ASan build)" make test From adc23e61320eac2ef7518d84e35b74a24b2ed995 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 25 Jun 2019 21:53:12 +0200 Subject: [PATCH 22/36] Adding ifdefs to avoid warnings for unused globals --- tests/fuzz/fuzz_client.c | 2 ++ tests/fuzz/fuzz_dtlsclient.c | 5 +++-- tests/fuzz/fuzz_dtlsserver.c | 4 +++- tests/fuzz/fuzz_server.c | 2 ++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/fuzz/fuzz_client.c b/tests/fuzz/fuzz_client.c index f2eaa3d335..38ad2fd566 100644 --- a/tests/fuzz/fuzz_client.c +++ b/tests/fuzz/fuzz_client.c @@ -9,6 +9,7 @@ #include +#ifdef MBEDTLS_SSL_CLI_C static bool initialized = 0; #if defined(MBEDTLS_X509_CRT_PARSE_C) static mbedtls_x509_crt cacert; @@ -25,6 +26,7 @@ const char psk_id[] = "Client_identity"; #endif const char *pers = "fuzz_client"; +#endif //MBEDTLS_SSL_CLI_C int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { diff --git a/tests/fuzz/fuzz_dtlsclient.c b/tests/fuzz/fuzz_dtlsclient.c index 4205917c18..fb872ef748 100644 --- a/tests/fuzz/fuzz_dtlsclient.c +++ b/tests/fuzz/fuzz_dtlsclient.c @@ -11,14 +11,15 @@ #include "mbedtls/timing.h" +#ifdef MBEDTLS_SSL_CLI_C static bool initialized = 0; #if defined(MBEDTLS_X509_CRT_PARSE_C) static mbedtls_x509_crt cacert; #endif - const char *pers = "fuzz_dtlsclient"; -#endif +#endif // MBEDTLS_SSL_CLI_C +#endif // MBEDTLS_SSL_PROTO_DTLS diff --git a/tests/fuzz/fuzz_dtlsserver.c b/tests/fuzz/fuzz_dtlsserver.c index 619661f5e2..ff9a60b72f 100644 --- a/tests/fuzz/fuzz_dtlsserver.c +++ b/tests/fuzz/fuzz_dtlsserver.c @@ -12,6 +12,7 @@ #include "mbedtls/ssl_cookie.h" +#ifdef MBEDTLS_SSL_SRV_C const char *pers = "fuzz_dtlsserver"; const unsigned char client_ip[4] = {0x7F, 0, 0, 1}; static bool initialized = 0; @@ -19,7 +20,8 @@ static bool initialized = 0; static mbedtls_x509_crt srvcert; static mbedtls_pk_context pkey; #endif -#endif +#endif // MBEDTLS_SSL_SRV_C +#endif // MBEDTLS_SSL_PROTO_DTLS int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { #if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_SSL_SRV_C) diff --git a/tests/fuzz/fuzz_server.c b/tests/fuzz/fuzz_server.c index 0a2f3a90c7..d751a71f83 100644 --- a/tests/fuzz/fuzz_server.c +++ b/tests/fuzz/fuzz_server.c @@ -10,6 +10,7 @@ #include +#ifdef MBEDTLS_SSL_SRV_C const char *pers = "fuzz_server"; static bool initialized = 0; #if defined(MBEDTLS_X509_CRT_PARSE_C) @@ -25,6 +26,7 @@ const unsigned char psk[] = { }; const char psk_id[] = "Client_identity"; #endif +#endif // MBEDTLS_SSL_SRV_C int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { From 1c582c3b8beae0aa6457650f2fd02baecb705076 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 25 Jun 2019 21:55:21 +0200 Subject: [PATCH 23/36] Restore tests/fuzz/Makefile after in-tree cmake Save and restore the Makefile in tests/fuzz like the other makefiles. --- tests/scripts/all.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index ca826b0b99..46107c923e 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -24,7 +24,8 @@ # configurations, and can and will arbitrarily change the current CMake # configuration. The following files must be committed into git: # * include/mbedtls/config.h -# * Makefile, library/Makefile, programs/Makefile, tests/Makefile +# * Makefile, library/Makefile, programs/Makefile, tests/Makefile, +# tests/fuzz/Makefile # After running this script, the CMake cache will be lost and CMake # will no longer be initialised. # @@ -75,9 +76,9 @@ # * Run `make clean`. # * Restore `include/mbedtks/config.h` from a backup made before running # the component. -# * Check out `Makefile`, `library/Makefile`, `programs/Makefile` and -# `tests/Makefile` from git. This cleans up after an in-tree use of -# CMake. +# * Check out `Makefile`, `library/Makefile`, `programs/Makefile`, +# `tests/Makefile` and `tests/fuzz/Makefile` from git. +# This cleans up after an in-tree use of CMake. # # Any command that is expected to fail must be protected so that the # script keeps running in --keep-going mode despite `set -e`. In keep-going @@ -234,8 +235,8 @@ cleanup() -iname CMakeCache.txt \) -exec rm {} \+ # Recover files overwritten by in-tree CMake builds rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile - git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile - git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile + git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile tests/fuzz/Makefile + git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile tests/fuzz/Makefile cd crypto rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile From cf8fdfd8e13d2e439bb4c5c2f91198eca02c44db Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 25 Jun 2019 22:06:35 +0200 Subject: [PATCH 24/36] Documentation for corpus generation --- tests/fuzz/README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/fuzz/README.md b/tests/fuzz/README.md index f208800ab8..8b24908f97 100644 --- a/tests/fuzz/README.md +++ b/tests/fuzz/README.md @@ -33,3 +33,36 @@ cmake .. make ``` Finally, you can run the targets like `./test/fuzz/fuzz_client`. + + +Corpus generation for network trafic targets +------ + +These targets use network trafic as inputs : +* client : simulates a client against (fuzzed) server traffic +* server : simulates a server against (fuzzed) client traffic +* dtls_client +* dtls_server + +They also use the last bytes as configuration options. + +To generate corpus for these targets, you can do the following, not fully automated steps : +* Build mbedtls programs ssl_server2 and ssl_client2 +* Run them one against the other with `reproducible` option turned on while capturing trafic into test.pcap +* Extract tcp payloads, for instance with tshark : `tshark -Tfields -e tcp.dstport -e tcp.payload -r test.pcap > test.txt` +* Run a dummy python script to output either client or server corpus file like `python dummy.py test.txt > test.cor` +* Finally, you can add the options by appending the last bytes to the file test.cor + +Here is an example of dummy.py for extracting payload from client to server (if we used `tcp.dstport` in tshark command) +``` +import sys +import binascii + +f = open(sys.argv[1]) +for l in f.readlines(): + portAndPl=l.split() + if len(portAndPl) == 2: + # determine client or server based on port + if portAndPl[0] == "4433": + print(binascii.unhexlify(portAndPl[1].replace(":",""))) +``` From 48f35f50bf4d2d16cefe671095bd80a5e49d0228 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 27 Jun 2019 08:46:45 +0200 Subject: [PATCH 25/36] Move fuzz directory to programs --- programs/CMakeLists.txt | 1 + programs/Makefile | 8 ++++++-- {tests => programs}/fuzz/.gitignore | 0 {tests => programs}/fuzz/CMakeLists.txt | 0 {tests => programs}/fuzz/Makefile | 0 {tests => programs}/fuzz/README.md | 0 {tests => programs}/fuzz/common.c | 0 {tests => programs}/fuzz/common.h | 0 {tests => programs}/fuzz/corpuses/client | Bin {tests => programs}/fuzz/corpuses/dtlsclient | Bin {tests => programs}/fuzz/corpuses/dtlsserver | Bin {tests => programs}/fuzz/corpuses/server | Bin {tests => programs}/fuzz/fuzz_client.c | 0 {tests => programs}/fuzz/fuzz_client.options | 0 {tests => programs}/fuzz/fuzz_dtlsclient.c | 0 {tests => programs}/fuzz/fuzz_dtlsclient.options | 0 {tests => programs}/fuzz/fuzz_dtlsserver.c | 0 {tests => programs}/fuzz/fuzz_dtlsserver.options | 0 {tests => programs}/fuzz/fuzz_privkey.c | 0 {tests => programs}/fuzz/fuzz_privkey.options | 0 {tests => programs}/fuzz/fuzz_pubkey.c | 0 {tests => programs}/fuzz/fuzz_pubkey.options | 0 {tests => programs}/fuzz/fuzz_server.c | 0 {tests => programs}/fuzz/fuzz_server.options | 0 {tests => programs}/fuzz/fuzz_x509crl.c | 0 {tests => programs}/fuzz/fuzz_x509crl.options | 0 {tests => programs}/fuzz/fuzz_x509crt.c | 0 {tests => programs}/fuzz/fuzz_x509crt.options | 0 {tests => programs}/fuzz/fuzz_x509csr.c | 0 {tests => programs}/fuzz/fuzz_x509csr.options | 0 {tests => programs}/fuzz/onefile.c | 0 tests/CMakeLists.txt | 2 -- tests/Makefile | 8 ++------ 33 files changed, 9 insertions(+), 10 deletions(-) rename {tests => programs}/fuzz/.gitignore (100%) rename {tests => programs}/fuzz/CMakeLists.txt (100%) rename {tests => programs}/fuzz/Makefile (100%) rename {tests => programs}/fuzz/README.md (100%) rename {tests => programs}/fuzz/common.c (100%) rename {tests => programs}/fuzz/common.h (100%) rename {tests => programs}/fuzz/corpuses/client (100%) rename {tests => programs}/fuzz/corpuses/dtlsclient (100%) rename {tests => programs}/fuzz/corpuses/dtlsserver (100%) rename {tests => programs}/fuzz/corpuses/server (100%) rename {tests => programs}/fuzz/fuzz_client.c (100%) rename {tests => programs}/fuzz/fuzz_client.options (100%) rename {tests => programs}/fuzz/fuzz_dtlsclient.c (100%) rename {tests => programs}/fuzz/fuzz_dtlsclient.options (100%) rename {tests => programs}/fuzz/fuzz_dtlsserver.c (100%) rename {tests => programs}/fuzz/fuzz_dtlsserver.options (100%) rename {tests => programs}/fuzz/fuzz_privkey.c (100%) rename {tests => programs}/fuzz/fuzz_privkey.options (100%) rename {tests => programs}/fuzz/fuzz_pubkey.c (100%) rename {tests => programs}/fuzz/fuzz_pubkey.options (100%) rename {tests => programs}/fuzz/fuzz_server.c (100%) rename {tests => programs}/fuzz/fuzz_server.options (100%) rename {tests => programs}/fuzz/fuzz_x509crl.c (100%) rename {tests => programs}/fuzz/fuzz_x509crl.options (100%) rename {tests => programs}/fuzz/fuzz_x509crt.c (100%) rename {tests => programs}/fuzz/fuzz_x509crt.options (100%) rename {tests => programs}/fuzz/fuzz_x509csr.c (100%) rename {tests => programs}/fuzz/fuzz_x509csr.options (100%) rename {tests => programs}/fuzz/onefile.c (100%) diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index 4cdae7821b..2350a2e24e 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -6,3 +6,4 @@ add_subdirectory(ssl) add_subdirectory(test) add_subdirectory(x509) add_subdirectory(util) +add_subdirectory(fuzz) diff --git a/programs/Makefile b/programs/Makefile index 2cb7366225..228a60e0fd 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -90,9 +90,12 @@ endif .SILENT: -.PHONY: all clean list +.PHONY: all clean list fuzz -all: $(APPS) +all: $(APPS) fuzz + +fuzz: + $(MAKE) -C fuzz $(DEP): $(MAKE) -C ../library @@ -305,6 +308,7 @@ ifndef WINDOWS else del /S /Q /F *.o *.exe endif + $(MAKE) -C fuzz clean list: echo $(APPS) diff --git a/tests/fuzz/.gitignore b/programs/fuzz/.gitignore similarity index 100% rename from tests/fuzz/.gitignore rename to programs/fuzz/.gitignore diff --git a/tests/fuzz/CMakeLists.txt b/programs/fuzz/CMakeLists.txt similarity index 100% rename from tests/fuzz/CMakeLists.txt rename to programs/fuzz/CMakeLists.txt diff --git a/tests/fuzz/Makefile b/programs/fuzz/Makefile similarity index 100% rename from tests/fuzz/Makefile rename to programs/fuzz/Makefile diff --git a/tests/fuzz/README.md b/programs/fuzz/README.md similarity index 100% rename from tests/fuzz/README.md rename to programs/fuzz/README.md diff --git a/tests/fuzz/common.c b/programs/fuzz/common.c similarity index 100% rename from tests/fuzz/common.c rename to programs/fuzz/common.c diff --git a/tests/fuzz/common.h b/programs/fuzz/common.h similarity index 100% rename from tests/fuzz/common.h rename to programs/fuzz/common.h diff --git a/tests/fuzz/corpuses/client b/programs/fuzz/corpuses/client similarity index 100% rename from tests/fuzz/corpuses/client rename to programs/fuzz/corpuses/client diff --git a/tests/fuzz/corpuses/dtlsclient b/programs/fuzz/corpuses/dtlsclient similarity index 100% rename from tests/fuzz/corpuses/dtlsclient rename to programs/fuzz/corpuses/dtlsclient diff --git a/tests/fuzz/corpuses/dtlsserver b/programs/fuzz/corpuses/dtlsserver similarity index 100% rename from tests/fuzz/corpuses/dtlsserver rename to programs/fuzz/corpuses/dtlsserver diff --git a/tests/fuzz/corpuses/server b/programs/fuzz/corpuses/server similarity index 100% rename from tests/fuzz/corpuses/server rename to programs/fuzz/corpuses/server diff --git a/tests/fuzz/fuzz_client.c b/programs/fuzz/fuzz_client.c similarity index 100% rename from tests/fuzz/fuzz_client.c rename to programs/fuzz/fuzz_client.c diff --git a/tests/fuzz/fuzz_client.options b/programs/fuzz/fuzz_client.options similarity index 100% rename from tests/fuzz/fuzz_client.options rename to programs/fuzz/fuzz_client.options diff --git a/tests/fuzz/fuzz_dtlsclient.c b/programs/fuzz/fuzz_dtlsclient.c similarity index 100% rename from tests/fuzz/fuzz_dtlsclient.c rename to programs/fuzz/fuzz_dtlsclient.c diff --git a/tests/fuzz/fuzz_dtlsclient.options b/programs/fuzz/fuzz_dtlsclient.options similarity index 100% rename from tests/fuzz/fuzz_dtlsclient.options rename to programs/fuzz/fuzz_dtlsclient.options diff --git a/tests/fuzz/fuzz_dtlsserver.c b/programs/fuzz/fuzz_dtlsserver.c similarity index 100% rename from tests/fuzz/fuzz_dtlsserver.c rename to programs/fuzz/fuzz_dtlsserver.c diff --git a/tests/fuzz/fuzz_dtlsserver.options b/programs/fuzz/fuzz_dtlsserver.options similarity index 100% rename from tests/fuzz/fuzz_dtlsserver.options rename to programs/fuzz/fuzz_dtlsserver.options diff --git a/tests/fuzz/fuzz_privkey.c b/programs/fuzz/fuzz_privkey.c similarity index 100% rename from tests/fuzz/fuzz_privkey.c rename to programs/fuzz/fuzz_privkey.c diff --git a/tests/fuzz/fuzz_privkey.options b/programs/fuzz/fuzz_privkey.options similarity index 100% rename from tests/fuzz/fuzz_privkey.options rename to programs/fuzz/fuzz_privkey.options diff --git a/tests/fuzz/fuzz_pubkey.c b/programs/fuzz/fuzz_pubkey.c similarity index 100% rename from tests/fuzz/fuzz_pubkey.c rename to programs/fuzz/fuzz_pubkey.c diff --git a/tests/fuzz/fuzz_pubkey.options b/programs/fuzz/fuzz_pubkey.options similarity index 100% rename from tests/fuzz/fuzz_pubkey.options rename to programs/fuzz/fuzz_pubkey.options diff --git a/tests/fuzz/fuzz_server.c b/programs/fuzz/fuzz_server.c similarity index 100% rename from tests/fuzz/fuzz_server.c rename to programs/fuzz/fuzz_server.c diff --git a/tests/fuzz/fuzz_server.options b/programs/fuzz/fuzz_server.options similarity index 100% rename from tests/fuzz/fuzz_server.options rename to programs/fuzz/fuzz_server.options diff --git a/tests/fuzz/fuzz_x509crl.c b/programs/fuzz/fuzz_x509crl.c similarity index 100% rename from tests/fuzz/fuzz_x509crl.c rename to programs/fuzz/fuzz_x509crl.c diff --git a/tests/fuzz/fuzz_x509crl.options b/programs/fuzz/fuzz_x509crl.options similarity index 100% rename from tests/fuzz/fuzz_x509crl.options rename to programs/fuzz/fuzz_x509crl.options diff --git a/tests/fuzz/fuzz_x509crt.c b/programs/fuzz/fuzz_x509crt.c similarity index 100% rename from tests/fuzz/fuzz_x509crt.c rename to programs/fuzz/fuzz_x509crt.c diff --git a/tests/fuzz/fuzz_x509crt.options b/programs/fuzz/fuzz_x509crt.options similarity index 100% rename from tests/fuzz/fuzz_x509crt.options rename to programs/fuzz/fuzz_x509crt.options diff --git a/tests/fuzz/fuzz_x509csr.c b/programs/fuzz/fuzz_x509csr.c similarity index 100% rename from tests/fuzz/fuzz_x509csr.c rename to programs/fuzz/fuzz_x509csr.c diff --git a/tests/fuzz/fuzz_x509csr.options b/programs/fuzz/fuzz_x509csr.options similarity index 100% rename from tests/fuzz/fuzz_x509csr.options rename to programs/fuzz/fuzz_x509csr.options diff --git a/tests/fuzz/onefile.c b/programs/fuzz/onefile.c similarity index 100% rename from tests/fuzz/onefile.c rename to programs/fuzz/onefile.c diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d060255bdb..ecf6f34b2f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -77,5 +77,3 @@ if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) link_to_source(scripts) link_to_source(ssl-opt.sh) endif() - -add_subdirectory(fuzz) diff --git a/tests/Makefile b/tests/Makefile index 2ca0fd6963..27ce338954 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -112,12 +112,9 @@ BINARIES := $(addsuffix $(EXEXT),$(APPS)) .SILENT: -.PHONY: all check test clean fuzz +.PHONY: all check test clean -all: $(BINARIES) fuzz - -fuzz: - $(MAKE) -C fuzz +all: $(BINARIES) $(DEP): $(MAKE) -C ../library @@ -164,7 +161,6 @@ ifneq ($(wildcard TESTS/.*),) rmdir /Q /S TESTS endif endif - $(MAKE) -C fuzz clean # Test suites caught by SKIP_TEST_SUITES are built but not executed. check: $(BINARIES) From 5dece6da2cba52dd6332d2bcf523cf7b8d47bda6 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 27 Jun 2019 16:55:07 +0200 Subject: [PATCH 26/36] Restore programs/fuzz/Makefile after in-tree cmake --- tests/scripts/all.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 46107c923e..253d62d298 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -25,7 +25,7 @@ # configuration. The following files must be committed into git: # * include/mbedtls/config.h # * Makefile, library/Makefile, programs/Makefile, tests/Makefile, -# tests/fuzz/Makefile +# programs/fuzz/Makefile # After running this script, the CMake cache will be lost and CMake # will no longer be initialised. # @@ -77,7 +77,7 @@ # * Restore `include/mbedtks/config.h` from a backup made before running # the component. # * Check out `Makefile`, `library/Makefile`, `programs/Makefile`, -# `tests/Makefile` and `tests/fuzz/Makefile` from git. +# `tests/Makefile` and `programs/fuzz/Makefile` from git. # This cleans up after an in-tree use of CMake. # # Any command that is expected to fail must be protected so that the @@ -235,8 +235,8 @@ cleanup() -iname CMakeCache.txt \) -exec rm {} \+ # Recover files overwritten by in-tree CMake builds rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile - git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile tests/fuzz/Makefile - git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile tests/fuzz/Makefile + git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile programs/fuzz/Makefile + git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile programs/fuzz/Makefile cd crypto rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile From daab28a4afd1008043fedc9395c4136212c3cf22 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Fri, 28 Jun 2019 12:31:23 +0200 Subject: [PATCH 27/36] checks MBEDTLS_PEM_PARSE_C --- programs/fuzz/fuzz_client.c | 8 ++++---- programs/fuzz/fuzz_dtlsclient.c | 8 ++++---- programs/fuzz/fuzz_dtlsserver.c | 6 +++--- programs/fuzz/fuzz_server.c | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/programs/fuzz/fuzz_client.c b/programs/fuzz/fuzz_client.c index 38ad2fd566..607a8d2b7e 100644 --- a/programs/fuzz/fuzz_client.c +++ b/programs/fuzz/fuzz_client.c @@ -11,7 +11,7 @@ #ifdef MBEDTLS_SSL_CLI_C static bool initialized = 0; -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) static mbedtls_x509_crt cacert; #endif const char *alpn_list[3]; @@ -42,7 +42,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { uint16_t options; if (initialized == 0) { -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) mbedtls_x509_crt_init( &cacert ); if (mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem, mbedtls_test_cas_pem_len ) != 0) @@ -88,7 +88,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { } #endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) if (options & 4) { mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED ); @@ -129,7 +129,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if( mbedtls_ssl_setup( &ssl, &conf ) != 0 ) goto exit; -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) if ((options & 1) == 0) { if( mbedtls_ssl_set_hostname( &ssl, "localhost" ) != 0 ) goto exit; diff --git a/programs/fuzz/fuzz_dtlsclient.c b/programs/fuzz/fuzz_dtlsclient.c index fb872ef748..7de8356742 100644 --- a/programs/fuzz/fuzz_dtlsclient.c +++ b/programs/fuzz/fuzz_dtlsclient.c @@ -13,7 +13,7 @@ #ifdef MBEDTLS_SSL_CLI_C static bool initialized = 0; -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) static mbedtls_x509_crt cacert; #endif @@ -36,7 +36,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { fuzzBufferOffset_t biomemfuzz; if (initialized == 0) { -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) mbedtls_x509_crt_init( &cacert ); if (mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem, mbedtls_test_cas_pem_len ) != 0) @@ -63,7 +63,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { MBEDTLS_SSL_PRESET_DEFAULT ) != 0 ) goto exit; -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); #endif mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE ); @@ -75,7 +75,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay ); -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) if( mbedtls_ssl_set_hostname( &ssl, "localhost" ) != 0 ) goto exit; #endif diff --git a/programs/fuzz/fuzz_dtlsserver.c b/programs/fuzz/fuzz_dtlsserver.c index ff9a60b72f..ec08f79ca7 100644 --- a/programs/fuzz/fuzz_dtlsserver.c +++ b/programs/fuzz/fuzz_dtlsserver.c @@ -16,7 +16,7 @@ const char *pers = "fuzz_dtlsserver"; const unsigned char client_ip[4] = {0x7F, 0, 0, 1}; static bool initialized = 0; -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) static mbedtls_x509_crt srvcert; static mbedtls_pk_context pkey; #endif @@ -37,7 +37,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { fuzzBufferOffset_t biomemfuzz; if (initialized == 0) { -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) mbedtls_x509_crt_init( &srvcert ); mbedtls_pk_init( &pkey ); if (mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) mbedtls_test_srv_crt, @@ -75,7 +75,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { srand(1); mbedtls_ssl_conf_rng( &conf, dummy_random, &ctr_drbg ); -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL ); if( mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) != 0 ) goto exit; diff --git a/programs/fuzz/fuzz_server.c b/programs/fuzz/fuzz_server.c index d751a71f83..94c80f6c3f 100644 --- a/programs/fuzz/fuzz_server.c +++ b/programs/fuzz/fuzz_server.c @@ -13,7 +13,7 @@ #ifdef MBEDTLS_SSL_SRV_C const char *pers = "fuzz_server"; static bool initialized = 0; -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) static mbedtls_x509_crt srvcert; static mbedtls_pk_context pkey; #endif @@ -51,7 +51,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { options = Data[Size - 1]; if (initialized == 0) { -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) mbedtls_x509_crt_init( &srvcert ); mbedtls_pk_init( &pkey ); if (mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) mbedtls_test_srv_crt, @@ -95,7 +95,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { srand(1); mbedtls_ssl_conf_rng( &conf, dummy_random, &ctr_drbg ); -#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL ); if( mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) != 0 ) goto exit; From 5131f771ef06cfdb6a5de4def6045229e7ea257f Mon Sep 17 00:00:00 2001 From: Ron Eldor Date: Tue, 25 Jun 2019 14:52:19 +0300 Subject: [PATCH 28/36] Fix parsing issue when int parameter is in base 16 Fix error `ValueError: invalid literal for int() with base 10:` that is caused when a parameter is given in base 16. Use relevant base when calling `int()` function. --- tests/scripts/mbedtls_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/scripts/mbedtls_test.py b/tests/scripts/mbedtls_test.py index b7b9dc0633..6ac68a4fb3 100755 --- a/tests/scripts/mbedtls_test.py +++ b/tests/scripts/mbedtls_test.py @@ -80,6 +80,7 @@ class TestDataParser(object): if len(split_char) > 1: raise ValueError('Expected split character. Found string!') out = list(map(split_colon_fn, re.split(r'(? Date: Wed, 3 Jul 2019 13:51:04 +0100 Subject: [PATCH 29/36] tests: Limit each log to 10 GiB Limit log output in compat.sh and ssl-opt.sh, in case of failures with these scripts where they may output seemingly unlimited length error logs. Note that ulimit -f uses units of 512 bytes, so we use 10 * 1024 * 1024 * 2 to get 10 GiB. --- tests/compat.sh | 4 ++++ tests/ssl-opt.sh | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tests/compat.sh b/tests/compat.sh index 0eae1eab36..80c2d31a3a 100755 --- a/tests/compat.sh +++ b/tests/compat.sh @@ -15,6 +15,10 @@ set -u +# Limit the size of each log to 10 GiB, in case of failures with this script +# where it may output seemingly unlimited length error logs. +ulimit -f 20971520 + # initialise counters TESTS=0 FAILED=0 diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index f54295b6ed..ed97f233ff 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -21,6 +21,10 @@ set -u +# Limit the size of each log to 10 GiB, in case of failures with this script +# where it may output seemingly unlimited length error logs. +ulimit -f 20971520 + if cd $( dirname $0 ); then :; else echo "cd $( dirname $0 ) failed" >&2 exit 1 From 702c65922f51c548a40a6fd4a112e7568cf9d207 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 9 Jul 2019 17:44:53 +0200 Subject: [PATCH 30/36] Add a linker flag to enable gcov in basic-build-test.sh --- tests/scripts/basic-build-test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh index 2c9deb9ba1..4b71ff69bb 100755 --- a/tests/scripts/basic-build-test.sh +++ b/tests/scripts/basic-build-test.sh @@ -64,6 +64,7 @@ echo # Step 1 - Make and instrumented build for code coverage export CFLAGS=' --coverage -g3 -O0 ' +export LDFLAGS=' --coverage' make clean cp "$CONFIG_H" "$CONFIG_BAK" scripts/config.pl full From 3e408d59c4f0071f140867ba7cc00ba44ad264b3 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Wed, 10 Jul 2019 01:09:50 +0200 Subject: [PATCH 31/36] Fixes warnings from MSVC --- programs/fuzz/common.c | 5 ++++- programs/fuzz/onefile.c | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/programs/fuzz/common.c b/programs/fuzz/common.c index a9d3d3b86f..169b4804fe 100644 --- a/programs/fuzz/common.c +++ b/programs/fuzz/common.c @@ -26,7 +26,10 @@ int dummy_send( void *ctx, const unsigned char *buf, size_t len ) (void) buf; //pretends we wrote everything ok - return( len ); + if (len > INT_MAX) { + return -1; + } + return int( len ); } int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) diff --git a/programs/fuzz/onefile.c b/programs/fuzz/onefile.c index 45c32829f6..c5361b310f 100644 --- a/programs/fuzz/onefile.c +++ b/programs/fuzz/onefile.c @@ -1,5 +1,4 @@ #include -#include #include #include From 2321945e4419a35337d77cd0e91866758bfa5533 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Wed, 10 Jul 2019 08:26:04 +0200 Subject: [PATCH 32/36] Syntax fix --- programs/fuzz/common.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/programs/fuzz/common.c b/programs/fuzz/common.c index 169b4804fe..df0da358bf 100644 --- a/programs/fuzz/common.c +++ b/programs/fuzz/common.c @@ -27,9 +27,9 @@ int dummy_send( void *ctx, const unsigned char *buf, size_t len ) //pretends we wrote everything ok if (len > INT_MAX) { - return -1; + return (-1); } - return int( len ); + return (int) ( len ); } int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) @@ -41,13 +41,16 @@ int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) //EOF return (0); } + if (len > INT_MAX) { + return (-1); + } if (len + biomemfuzz->Offset > biomemfuzz->Size) { //do not overflow len = biomemfuzz->Size - biomemfuzz->Offset; } memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); biomemfuzz->Offset += len; - return( len ); + return (int) ( len ); } int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) From b3d3127d01217aa313c5accd9823759ee5e9a174 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Wed, 10 Jul 2019 13:34:51 +0200 Subject: [PATCH 33/36] Style corrections --- programs/fuzz/common.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/programs/fuzz/common.c b/programs/fuzz/common.c index df0da358bf..d7823eb5fc 100644 --- a/programs/fuzz/common.c +++ b/programs/fuzz/common.c @@ -26,10 +26,10 @@ int dummy_send( void *ctx, const unsigned char *buf, size_t len ) (void) buf; //pretends we wrote everything ok - if (len > INT_MAX) { - return (-1); + if ( len > INT_MAX ) { + return ( -1 ); } - return (int) ( len ); + return ( (int) len ); } int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) @@ -39,18 +39,18 @@ int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) if (biomemfuzz->Offset == biomemfuzz->Size) { //EOF - return (0); + return ( 0 ); } - if (len > INT_MAX) { - return (-1); + if ( len > INT_MAX ) { + return ( -1 ); } - if (len + biomemfuzz->Offset > biomemfuzz->Size) { + if ( len + biomemfuzz->Offset > biomemfuzz->Size ) { //do not overflow len = biomemfuzz->Size - biomemfuzz->Offset; } memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); biomemfuzz->Offset += len; - return (int) ( len ); + return ( (int) len ); } int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) From a82fdd47635fa415e42cae1ece07d3c095bfe743 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Wed, 10 Jul 2019 13:53:40 +0200 Subject: [PATCH 34/36] Removing space before opening parenthesis --- programs/fuzz/common.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/programs/fuzz/common.c b/programs/fuzz/common.c index d7823eb5fc..5e6c84c268 100644 --- a/programs/fuzz/common.c +++ b/programs/fuzz/common.c @@ -26,10 +26,10 @@ int dummy_send( void *ctx, const unsigned char *buf, size_t len ) (void) buf; //pretends we wrote everything ok - if ( len > INT_MAX ) { - return ( -1 ); + if( len > INT_MAX ) { + return( -1 ); } - return ( (int) len ); + return( (int) len ); } int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) @@ -37,20 +37,20 @@ int fuzz_recv( void *ctx, unsigned char *buf, size_t len ) //reads from the buffer from fuzzer fuzzBufferOffset_t * biomemfuzz = (fuzzBufferOffset_t *) ctx; - if (biomemfuzz->Offset == biomemfuzz->Size) { + if(biomemfuzz->Offset == biomemfuzz->Size) { //EOF - return ( 0 ); + return( 0 ); } - if ( len > INT_MAX ) { - return ( -1 ); + if( len > INT_MAX ) { + return( -1 ); } - if ( len + biomemfuzz->Offset > biomemfuzz->Size ) { + if( len + biomemfuzz->Offset > biomemfuzz->Size ) { //do not overflow len = biomemfuzz->Size - biomemfuzz->Offset; } memcpy(buf, biomemfuzz->Data + biomemfuzz->Offset, len); biomemfuzz->Offset += len; - return ( (int) len ); + return( (int) len ); } int dummy_random( void *p_rng, unsigned char *output, size_t output_len ) From 42a2ce8255e75ea54182e21e9ff611c1c9d19f22 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Wed, 10 Jul 2019 14:26:31 +0200 Subject: [PATCH 35/36] No booleans and import config --- programs/fuzz/fuzz_client.c | 3 +-- programs/fuzz/fuzz_dtlsclient.c | 3 +-- programs/fuzz/fuzz_dtlsserver.c | 3 +-- programs/fuzz/fuzz_server.c | 3 +-- programs/fuzz/onefile.c | 2 ++ 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/programs/fuzz/fuzz_client.c b/programs/fuzz/fuzz_client.c index 607a8d2b7e..ca7a8ab7cc 100644 --- a/programs/fuzz/fuzz_client.c +++ b/programs/fuzz/fuzz_client.c @@ -5,12 +5,11 @@ #include "common.h" #include #include -#include #include #ifdef MBEDTLS_SSL_CLI_C -static bool initialized = 0; +static int initialized = 0; #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) static mbedtls_x509_crt cacert; #endif diff --git a/programs/fuzz/fuzz_dtlsclient.c b/programs/fuzz/fuzz_dtlsclient.c index 7de8356742..8197a6484d 100644 --- a/programs/fuzz/fuzz_dtlsclient.c +++ b/programs/fuzz/fuzz_dtlsclient.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "common.h" #include "mbedtls/ssl.h" @@ -12,7 +11,7 @@ #ifdef MBEDTLS_SSL_CLI_C -static bool initialized = 0; +static int initialized = 0; #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) static mbedtls_x509_crt cacert; #endif diff --git a/programs/fuzz/fuzz_dtlsserver.c b/programs/fuzz/fuzz_dtlsserver.c index ec08f79ca7..9e9fe8ebde 100644 --- a/programs/fuzz/fuzz_dtlsserver.c +++ b/programs/fuzz/fuzz_dtlsserver.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "common.h" #include "mbedtls/ssl.h" @@ -15,7 +14,7 @@ #ifdef MBEDTLS_SSL_SRV_C const char *pers = "fuzz_dtlsserver"; const unsigned char client_ip[4] = {0x7F, 0, 0, 1}; -static bool initialized = 0; +static int initialized = 0; #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) static mbedtls_x509_crt srvcert; static mbedtls_pk_context pkey; diff --git a/programs/fuzz/fuzz_server.c b/programs/fuzz/fuzz_server.c index 94c80f6c3f..7cb592238c 100644 --- a/programs/fuzz/fuzz_server.c +++ b/programs/fuzz/fuzz_server.c @@ -6,13 +6,12 @@ #include "common.h" #include #include -#include #include #ifdef MBEDTLS_SSL_SRV_C const char *pers = "fuzz_server"; -static bool initialized = 0; +static int initialized = 0; #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C) static mbedtls_x509_crt srvcert; static mbedtls_pk_context pkey; diff --git a/programs/fuzz/onefile.c b/programs/fuzz/onefile.c index c5361b310f..9e3986d6b7 100644 --- a/programs/fuzz/onefile.c +++ b/programs/fuzz/onefile.c @@ -1,6 +1,8 @@ #include #include #include +// Get platform-specific definition +#include "mbedtls/config.h" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); From a864db0dd62352981e8f550ca4475524384408ec Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Wed, 10 Jul 2019 20:37:57 +0200 Subject: [PATCH 36/36] Do not build fuzz on windows --- programs/CMakeLists.txt | 4 +++- programs/Makefile | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index 2350a2e24e..2af4d119ac 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -6,4 +6,6 @@ add_subdirectory(ssl) add_subdirectory(test) add_subdirectory(x509) add_subdirectory(util) -add_subdirectory(fuzz) +if (NOT WIN32) + add_subdirectory(fuzz) +endif() diff --git a/programs/Makefile b/programs/Makefile index 228a60e0fd..1d14b701e0 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -92,7 +92,13 @@ endif .PHONY: all clean list fuzz -all: $(APPS) fuzz +all: $(APPS) +ifndef WINDOWS +# APPS doesn't include the fuzzing programs, which aren't "normal" +# sample or test programs, and don't build with MSVC which is +# warning about fopen +all: fuzz +endif fuzz: $(MAKE) -C fuzz