aboutsummaryrefslogtreecommitdiff
path: root/fuzz
diff options
context:
space:
mode:
authorNardi Ivan <nardi.ivan@gmail.com>2023-10-13 15:57:35 +0200
committerIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2023-10-15 12:00:26 +0200
commit16b4913be6395f79e98287e4d32dc5daf2d3f5c7 (patch)
tree8a45fd9eb15a68a00f8b103e4262defeb500eb8c /fuzz
parentb6179467ebdf8c0ee1667cbe9390b3b76e82578f (diff)
fuzz: extend fuzzing coverage
Diffstat (limited to 'fuzz')
-rw-r--r--fuzz/Makefile.am17
-rw-r--r--fuzz/fuzz_gcrypt_cipher.cpp105
-rw-r--r--fuzz/fuzz_gcrypt_gcm.cpp1
-rw-r--r--fuzz/fuzz_libinjection.c3
-rw-r--r--fuzz/fuzz_ndpi_reader.c2
-rw-r--r--fuzz/fuzz_ndpi_reader_payload_analyzer.options2
6 files changed, 127 insertions, 3 deletions
diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am
index 3d865a253..5f6fbb71c 100644
--- a/fuzz/Makefile.am
+++ b/fuzz/Makefile.am
@@ -6,7 +6,7 @@ bin_PROGRAMS += fuzz_ds_patricia fuzz_ds_ahocorasick fuzz_ds_libcache fuzz_ds_tr
#Third party
bin_PROGRAMS += fuzz_libinjection fuzz_binaryfusefilter
#Internal crypto
-bin_PROGRAMS += fuzz_gcrypt_light fuzz_gcrypt_aes fuzz_gcrypt_gcm
+bin_PROGRAMS += fuzz_gcrypt_light fuzz_gcrypt_aes fuzz_gcrypt_gcm fuzz_gcrypt_cipher
#Configuration files
bin_PROGRAMS += fuzz_filecfg_protocols
#Reader utils
@@ -457,6 +457,21 @@ fuzz_gcrypt_gcm_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \
$(fuzz_gcrypt_gcm_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@
+fuzz_gcrypt_cipher_SOURCES = fuzz_gcrypt_cipher.cpp
+fuzz_gcrypt_cipher_CXXFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS) -I ../src/lib/third_party/include/
+fuzz_gcrypt_cipher_CFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS) -I ../src/lib/third_party/include/
+fuzz_gcrypt_cipher_LDADD = ../src/lib/libndpi.a $(ADDITIONAL_LIBS)
+fuzz_gcrypt_cipher_LDFLAGS = $(LIBS)
+if HAS_FUZZLDFLAGS
+fuzz_gcrypt_cipher_CXXFLAGS += $(LIB_FUZZING_ENGINE)
+fuzz_gcrypt_cipher_CFLAGS += $(LIB_FUZZING_ENGINE)
+fuzz_gcrypt_cipher_LDFLAGS += $(LIB_FUZZING_ENGINE)
+endif
+# force usage of CXX for linker
+fuzz_gcrypt_cipher_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \
+ $(fuzz_gcrypt_cipher_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@
+
fuzz_filecfg_protocols_SOURCES = fuzz_filecfg_protocols.c fuzz_common_code.c
fuzz_filecfg_protocols_CFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS)
fuzz_filecfg_protocols_LDADD = ../src/lib/libndpi.a $(ADDITIONAL_LIBS)
diff --git a/fuzz/fuzz_gcrypt_cipher.cpp b/fuzz/fuzz_gcrypt_cipher.cpp
new file mode 100644
index 000000000..7eaffcdc2
--- /dev/null
+++ b/fuzz/fuzz_gcrypt_cipher.cpp
@@ -0,0 +1,105 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <assert.h>
+#include "fuzzer/FuzzedDataProvider.h"
+
+#define MBEDTLS_CHECK_RETURN_TYPICAL
+#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 )
+#include "../src/lib/third_party/include/gcrypt/cipher.h"
+#include "../src/lib/third_party/include/gcrypt/aes.h"
+
+extern int force_no_aesni;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ FuzzedDataProvider fuzzed_data(data, size);
+ int key_lens[] = { 128, 192, 256 };
+ int key_len, iv_len, rc_e, rc_d, input_length;
+ unsigned char *output, *decrypted;
+ size_t output_size, output_size2, decrypted_size;
+ mbedtls_cipher_type_t cipher_type;
+ /* TODO: GCM. This code/fuzzer doesn't work with GCM ciphers. Not sure why.. :( */
+ const char *cipher_names[] = { NULL, "", "AES-128-ECB", "AES-192-ECB", "AES-256-ECB",
+ /* "AES-128-GCM", "AES-192-GCM", "AES-256-GCM" */ };
+ const char *cipher_name;
+ mbedtls_cipher_context_t *ctx_e, *ctx_d;
+
+ /* No real memory allocations involved */
+
+ if(fuzzed_data.remaining_bytes() < 512) /* Some data */
+ return -1;
+
+ posix_memalign((void **)&ctx_e, 8, sizeof(mbedtls_cipher_context_t));
+ posix_memalign((void **)&ctx_d, 8, sizeof(mbedtls_cipher_context_t));
+
+ key_len = fuzzed_data.PickValueInArray(key_lens);
+ std::vector<unsigned char>key = fuzzed_data.ConsumeBytes<u_int8_t>(key_len / 8);
+ iv_len = fuzzed_data.ConsumeIntegralInRange(0, MBEDTLS_MAX_IV_LENGTH + 1);
+ std::vector<u_int8_t>iv = fuzzed_data.ConsumeBytes<uint8_t>(iv_len);
+ input_length = fuzzed_data.ConsumeIntegralInRange(16, 17);
+ std::vector<unsigned char>input = fuzzed_data.ConsumeBytes<u_int8_t>(input_length);
+ output = (unsigned char *)malloc(input_length);
+ decrypted = (unsigned char *)malloc(input_length);
+
+ mbedtls_cipher_list();
+ /* Random iteration */
+ cipher_type = static_cast<mbedtls_cipher_type_t>(fuzzed_data.ConsumeIntegralInRange(0, (int)MBEDTLS_CIPHER_AES_256_KWP) + 1);
+ mbedtls_cipher_info_from_type(cipher_type);
+
+ /* Real cipher used */
+ cipher_name = cipher_names[fuzzed_data.ConsumeIntegralInRange(0, (int)(sizeof(cipher_names) / sizeof(char *) - 1))];
+ mbedtls_cipher_init(ctx_e);
+ mbedtls_cipher_init(ctx_d);
+ ctx_e->cipher_info = mbedtls_cipher_info_from_string(cipher_name);
+ ctx_d->cipher_info = ctx_e->cipher_info;
+
+ mbedtls_cipher_info_get_mode(ctx_e->cipher_info);
+ mbedtls_cipher_info_get_type(ctx_e->cipher_info);
+ mbedtls_cipher_info_get_name(ctx_e->cipher_info);
+ mbedtls_cipher_info_has_variable_key_bitlen(ctx_e->cipher_info);
+ mbedtls_cipher_info_get_iv_size(ctx_e->cipher_info);
+ mbedtls_cipher_info_get_block_size(ctx_e->cipher_info);
+ mbedtls_cipher_get_cipher_mode(ctx_e);
+ mbedtls_cipher_info_get_key_bitlen(ctx_e->cipher_info);
+
+ posix_memalign((void **)&ctx_e->cipher_ctx, 8, sizeof(mbedtls_aes_context));
+ posix_memalign((void **)&ctx_d->cipher_ctx, 8, sizeof(mbedtls_aes_context));
+
+ rc_e = mbedtls_cipher_setkey(ctx_e, key.data(), key.size() * 8, MBEDTLS_ENCRYPT);
+ rc_d = mbedtls_cipher_setkey(ctx_d, key.data(), key.size() * 8, MBEDTLS_DECRYPT);
+ if(rc_e == 0 && rc_d == 0) {
+ rc_e = mbedtls_cipher_set_iv(ctx_e, iv.data(), iv.size());
+ rc_d = mbedtls_cipher_set_iv(ctx_d, iv.data(), iv.size());
+ if(rc_e == 0 && rc_d == 0) {
+ mbedtls_cipher_reset(ctx_e);
+ mbedtls_cipher_reset(ctx_d);
+
+ rc_e = mbedtls_cipher_update(ctx_e, input.data(), input.size(), output, &output_size);
+ if(rc_e == 0) {
+ rc_e = mbedtls_cipher_finish(ctx_e, NULL, &output_size2);
+ if(rc_e == 0) {
+
+ rc_d = mbedtls_cipher_update(ctx_d, output, output_size, decrypted, &decrypted_size);
+ if(rc_d == 0) {
+ rc_d = mbedtls_cipher_finish(ctx_d, NULL, &output_size2);
+ /* TODO: decryption doesn't work with no-aesni data path!
+ Note that with MASAN, aesni is always disabled */
+#if 0
+ if(rc_d == 0) {
+ assert(input.size() == decrypted_size);
+ assert(memcmp(input.data(), decrypted, decrypted_size) == 0);
+ }
+#endif
+ }
+ }
+ }
+ }
+ }
+
+ free(output);
+ free(decrypted);
+ free(ctx_e->cipher_ctx);
+ free(ctx_e);
+ free(ctx_d->cipher_ctx);
+ free(ctx_d);
+ return 0;
+}
diff --git a/fuzz/fuzz_gcrypt_gcm.cpp b/fuzz/fuzz_gcrypt_gcm.cpp
index fb2b0a931..debead9b4 100644
--- a/fuzz/fuzz_gcrypt_gcm.cpp
+++ b/fuzz/fuzz_gcrypt_gcm.cpp
@@ -37,7 +37,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
aes_e_ctx = (mbedtls_aes_context *)malloc(sizeof(mbedtls_aes_context));
aes_d_ctx = (mbedtls_aes_context *)malloc(sizeof(mbedtls_aes_context));
- /* Not sure if it is really necessary... */
force_no_aesni = 0;
if(fuzzed_data.ConsumeBool())
force_no_aesni = 1;
diff --git a/fuzz/fuzz_libinjection.c b/fuzz/fuzz_libinjection.c
index b1d897d23..afe272d51 100644
--- a/fuzz/fuzz_libinjection.c
+++ b/fuzz/fuzz_libinjection.c
@@ -5,6 +5,7 @@
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
struct libinjection_sqli_state state;
+ char fingerprint[8];
/* No memory allocations involved */
@@ -21,6 +22,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
libinjection_sqli_init(&state, (char *)data, size, FLAG_QUOTE_DOUBLE | FLAG_SQL_MYSQL);
libinjection_is_sqli(&state);
+ libinjection_sqli((char *)data, size, fingerprint);
+
libinjection_xss((char *)data, size);
libinjection_version();
diff --git a/fuzz/fuzz_ndpi_reader.c b/fuzz/fuzz_ndpi_reader.c
index 8b1674c9b..fd7d185e1 100644
--- a/fuzz/fuzz_ndpi_reader.c
+++ b/fuzz/fuzz_ndpi_reader.c
@@ -141,7 +141,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
ndpi_free(workflow->ndpi_flows_root);
/* Free payload analyzer data, without printing */
if(enable_payload_analyzer)
- ndpi_report_payload_stats(NULL);
+ ndpi_report_payload_stats(stdout);
#ifdef ENABLE_PAYLOAD_ANALYZER
ndpi_update_params(SPLT_PARAM_TYPE, "splt_param.txt");
diff --git a/fuzz/fuzz_ndpi_reader_payload_analyzer.options b/fuzz/fuzz_ndpi_reader_payload_analyzer.options
new file mode 100644
index 000000000..1c815b33f
--- /dev/null
+++ b/fuzz/fuzz_ndpi_reader_payload_analyzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+close_fd_mask=1