diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2023-04-04 14:19:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-04 14:19:41 +0200 |
commit | cc5aec5f0ac6ff3d7d4c9ecbe02881641e8c8c92 (patch) | |
tree | a1acafaa0f86978e648de0a75713873744ea8270 /fuzz/fuzz_gcrypt_light.cpp | |
parent | d7662379b470191afd5f5d3b26f4e0763bc24a83 (diff) |
fuzz: add fuzzer to test internal gcrypt code (#1920)
Diffstat (limited to 'fuzz/fuzz_gcrypt_light.cpp')
-rw-r--r-- | fuzz/fuzz_gcrypt_light.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/fuzz/fuzz_gcrypt_light.cpp b/fuzz/fuzz_gcrypt_light.cpp new file mode 100644 index 000000000..f75d38bee --- /dev/null +++ b/fuzz/fuzz_gcrypt_light.cpp @@ -0,0 +1,124 @@ +#include "fuzz_common_code.h" + +#include <stdint.h> +#include <stdio.h> +#include <assert.h> +#include "fuzzer/FuzzedDataProvider.h" + +#ifdef HAVE_LIBGCRYPT +#include "gcrypt.h" +#define HMAC_SHA256_DIGEST_SIZE 32 +#else +#include "../src/lib/third_party/include/gcrypt_light.h" +#endif + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + FuzzedDataProvider fuzzed_data(data, size); + gcry_md_hd_t hh; + gcry_cipher_hd_t h; + gcry_error_t rc; + int algo = 0, flags = 0, mode = 0; /* Invalid values */ + int key_len, iv_len, auth_len; + u_int8_t out[HMAC_SHA256_DIGEST_SIZE]; + char buf_err[16]; + void *enc_out; + + /* To allow memory allocation failures */ + fuzz_set_alloc_callbacks_and_seed(size); + + /* MD */ + + if(fuzzed_data.ConsumeBool()) + algo = GCRY_MD_SHA256; + if(fuzzed_data.ConsumeBool()) + flags = GCRY_MD_FLAG_HMAC; + key_len = fuzzed_data.ConsumeIntegralInRange(0, 65); /* Max valid key length is 64 */ + std::vector<u_int8_t>key = fuzzed_data.ConsumeBytes<u_int8_t>(key_len); + std::vector<u_int8_t>src = fuzzed_data.ConsumeBytes<uint8_t>(300); + + gcry_md_get_algo_dlen(algo); + rc = gcry_md_open(&hh, algo, flags); + if (rc == 0) { + gcry_md_reset(hh); + rc = gcry_md_setkey(hh, key.data(), key.size()); + if (rc == 0) { + if(fuzzed_data.ConsumeBool()) { /* To trigger MBEDTLS_ERR_MD_REKEY */ + rc = gcry_md_setkey(hh, key.data(), key.size()); + } else { + rc = gcry_md_write(hh, src.data(), src.size()); + if (rc == 0) { + memcpy(out, gcry_md_read(hh, 0), gcry_md_get_algo_dlen(algo)); + gcry_md_get_algo(hh); + } + } + } + gcry_md_close(hh); + } + gpg_strerror_r(rc, buf_err, sizeof(buf_err)); + + + /* Encryption */ + + /* ECB */ + + if(fuzzed_data.ConsumeBool()) + algo = GCRY_CIPHER_AES128; + if(fuzzed_data.ConsumeBool()) + flags = 1; /* Invalid value */ + if(fuzzed_data.ConsumeBool()) + mode = GCRY_CIPHER_MODE_ECB; + key_len = fuzzed_data.ConsumeIntegralInRange(16, 17); /* Only 16 is a valid key length */ + std::vector<u_int8_t>key2 = fuzzed_data.ConsumeBytes<u_int8_t>(key_len); + enc_out = ndpi_malloc(src.size()); + if (!enc_out) + return 0; + + rc = gcry_cipher_open(&h, algo, mode, flags); + if (rc == 0) { + rc = gcry_cipher_setkey(h, key2.data(), key2.size()); + if (rc == 0) { + if(fuzzed_data.ConsumeBool()) { /* To trigger MBEDTLS_ERR_CIPHER_BAD_KEY */ + rc = gcry_cipher_setkey(h, key2.data(), key2.size()); + } else { + rc = gcry_cipher_encrypt(h, enc_out, src.size(), src.data(), src.size()); + } + } + gcry_cipher_ctl(h, 0, NULL, 0); + gcry_cipher_close(h); + } + gpg_strerror_r(rc, buf_err, sizeof(buf_err)); + + /* GCM */ + + if(fuzzed_data.ConsumeBool()) + mode = GCRY_CIPHER_MODE_GCM; + iv_len = fuzzed_data.ConsumeIntegralInRange(12, 12); /* Only 12 is a valid key length */ + std::vector<u_int8_t>iv = fuzzed_data.ConsumeBytes<u_int8_t>(iv_len); + auth_len = fuzzed_data.ConsumeIntegralInRange(0, 257); /* 257 is an invalid value */ + std::vector<u_int8_t>auth = fuzzed_data.ConsumeBytes<u_int8_t>(auth_len); + + rc = gcry_cipher_open(&h, algo, mode, flags); + if (rc == 0) { + rc = gcry_cipher_setkey(h, key2.data(), key2.size()); + if (rc == 0) { + gcry_cipher_reset(h); + rc = gcry_cipher_setiv(h, iv.data(), iv.size()); + if (rc == 0) { + if(fuzzed_data.ConsumeBool()) { /* To trigger MBEDTLS_ERR_CIPHER_BAD_KEY */ + rc = gcry_cipher_setiv(h, iv.data(), iv.size()); + } else { + rc = gcry_cipher_authenticate(h, auth.data(), auth.size()); + if (rc == 0) { + rc = gcry_cipher_decrypt(h, enc_out, src.size(), src.data(), src.size()); + } + } + } + } + gcry_cipher_close(h); + } + gpg_strerror_r(rc, buf_err, sizeof(buf_err)); + + ndpi_free(enc_out); + + return 0; +} |