/src/ndpi/fuzz/fuzz_gcrypt_light.cpp
Line | Count | Source |
1 | | #include "fuzz_common_code.h" |
2 | | |
3 | | #include <stdint.h> |
4 | | #include <stdio.h> |
5 | | #include <assert.h> |
6 | | #include "fuzzer/FuzzedDataProvider.h" |
7 | | |
8 | | #ifdef HAVE_LIBGCRYPT |
9 | | #include "gcrypt.h" |
10 | | #define HMAC_SHA256_DIGEST_SIZE 32 |
11 | | #else |
12 | | #include "../src/lib/third_party/include/gcrypt_light.h" |
13 | | #endif |
14 | | |
15 | 667 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
16 | 667 | FuzzedDataProvider fuzzed_data(data, size); |
17 | 667 | gcry_md_hd_t hh; |
18 | 667 | gcry_cipher_hd_t h; |
19 | 667 | gcry_error_t rc; |
20 | 667 | int algo = 0, flags = 0, mode = 0; /* Invalid values */ |
21 | 667 | int key_len, iv_len, auth_len; |
22 | 667 | u_int8_t out[HMAC_SHA256_DIGEST_SIZE]; |
23 | 667 | char buf_err[16]; |
24 | 667 | void *enc_out; |
25 | | |
26 | | /* To allow memory allocation failures */ |
27 | 667 | fuzz_set_alloc_callbacks_and_seed(size); |
28 | | |
29 | 667 | gcry_control(fuzzed_data.ConsumeIntegralInRange(0, 2), |
30 | 667 | fuzzed_data.ConsumeIntegralInRange(0, 1)); |
31 | | |
32 | | /* MD */ |
33 | | |
34 | 667 | if(fuzzed_data.ConsumeBool()) |
35 | 341 | algo = GCRY_MD_SHA256; |
36 | 667 | if(fuzzed_data.ConsumeBool()) |
37 | 202 | flags = GCRY_MD_FLAG_HMAC; |
38 | 667 | key_len = fuzzed_data.ConsumeIntegralInRange(0, 65); /* Max valid key length is 64 */ |
39 | 667 | std::vector<u_int8_t>key = fuzzed_data.ConsumeBytes<u_int8_t>(key_len); |
40 | 667 | std::vector<u_int8_t>src = fuzzed_data.ConsumeBytes<uint8_t>(300); |
41 | | |
42 | 667 | gcry_md_get_algo_dlen(algo); |
43 | 667 | rc = gcry_md_open(&hh, algo, flags); |
44 | 667 | if (rc == 0) { |
45 | 153 | gcry_md_reset(hh); |
46 | 153 | rc = gcry_md_setkey(hh, key.data(), key.size()); |
47 | 153 | if (rc == 0) { |
48 | 153 | if(fuzzed_data.ConsumeBool()) { /* To trigger MBEDTLS_ERR_MD_REKEY */ |
49 | 38 | rc = gcry_md_setkey(hh, key.data(), key.size()); |
50 | 115 | } else { |
51 | 115 | rc = gcry_md_write(hh, src.data(), src.size()); |
52 | 115 | if (rc == 0) { |
53 | 96 | memcpy(out, gcry_md_read(hh, 0), gcry_md_get_algo_dlen(algo)); |
54 | 96 | gcry_md_get_algo(hh); |
55 | 96 | } |
56 | 115 | } |
57 | 153 | } |
58 | 153 | gcry_md_close(hh); |
59 | 153 | } |
60 | 667 | gpg_strerror_r(rc, buf_err, sizeof(buf_err)); |
61 | | |
62 | | |
63 | | /* Encryption */ |
64 | | |
65 | | /* ECB */ |
66 | | |
67 | 667 | if(fuzzed_data.ConsumeBool()) |
68 | 321 | algo = GCRY_CIPHER_AES128; |
69 | 667 | if(fuzzed_data.ConsumeBool()) |
70 | 87 | flags = 1; /* Invalid value */ |
71 | 667 | if(fuzzed_data.ConsumeBool()) |
72 | 272 | mode = GCRY_CIPHER_MODE_ECB; |
73 | 667 | key_len = fuzzed_data.ConsumeIntegralInRange(16, 17); /* Only 16 is a valid key length */ |
74 | 667 | std::vector<u_int8_t>key2 = fuzzed_data.ConsumeBytes<u_int8_t>(key_len); |
75 | 667 | enc_out = ndpi_malloc(src.size()); |
76 | 667 | if (!enc_out) |
77 | 23 | return 0; |
78 | | |
79 | 644 | h = NULL; |
80 | 644 | rc = gcry_cipher_open(&h, algo, mode, flags); |
81 | 644 | gpg_strerror_r(rc, buf_err, sizeof(buf_err)); |
82 | 644 | if(fuzzed_data.ConsumeBool()) |
83 | 208 | gcry_cipher_setkey(h, key2.data(), key2.size()); |
84 | 644 | if(fuzzed_data.ConsumeBool()) /* To trigger MBEDTLS_ERR_CIPHER_BAD_KEY */ |
85 | 165 | gcry_cipher_setkey(h, key2.data(), key2.size()); |
86 | 644 | rc = gcry_cipher_decrypt(h, enc_out, src.size(), src.data(), src.size()); |
87 | 644 | gpg_strerror_r(rc, buf_err, sizeof(buf_err)); |
88 | 644 | rc = gcry_cipher_encrypt(h, enc_out, src.size(), src.data(), src.size()); |
89 | 644 | gcry_cipher_ctl(h, 0, NULL, 0); |
90 | 644 | gcry_cipher_close(h); |
91 | | |
92 | 644 | gpg_strerror_r(rc, buf_err, sizeof(buf_err)); |
93 | | |
94 | | /* GCM */ |
95 | | |
96 | 644 | if(fuzzed_data.ConsumeBool()) |
97 | 247 | mode = GCRY_CIPHER_MODE_GCM; |
98 | 644 | iv_len = fuzzed_data.ConsumeIntegralInRange(12, 12); /* Only 12 is a valid key length */ |
99 | 644 | std::vector<u_int8_t>iv = fuzzed_data.ConsumeBytes<u_int8_t>(iv_len); |
100 | 644 | auth_len = fuzzed_data.ConsumeIntegralInRange(0, 257); /* 257 is an invalid value */ |
101 | 644 | std::vector<u_int8_t>auth = fuzzed_data.ConsumeBytes<u_int8_t>(auth_len); |
102 | | |
103 | 644 | h = NULL; |
104 | 644 | rc = gcry_cipher_open(&h, algo, mode, flags); |
105 | 644 | gpg_strerror_r(rc, buf_err, sizeof(buf_err)); |
106 | 644 | if(fuzzed_data.ConsumeBool()) { |
107 | 184 | rc = gcry_cipher_setkey(h, key2.data(), key2.size()); |
108 | 184 | gpg_strerror_r(rc, buf_err, sizeof(buf_err)); |
109 | 184 | } |
110 | 644 | if(fuzzed_data.ConsumeBool()) |
111 | 137 | gcry_cipher_reset(h); |
112 | 644 | rc = gcry_cipher_setiv(h, iv.data(), iv.size()); |
113 | 644 | gpg_strerror_r(rc, buf_err, sizeof(buf_err)); |
114 | 644 | if(fuzzed_data.ConsumeBool()) { /* To trigger MBEDTLS_ERR_CIPHER_BAD_KEY */ |
115 | 123 | rc = gcry_cipher_setiv(h, iv.data(), iv.size()); |
116 | 521 | } else { |
117 | 521 | rc = gcry_cipher_authenticate(h, auth.data(), auth.size()); |
118 | 521 | if (rc == 0) { |
119 | 129 | rc = gcry_cipher_encrypt(h, enc_out, src.size(), src.data(), src.size()); |
120 | 129 | gpg_strerror_r(rc, buf_err, sizeof(buf_err)); |
121 | 129 | rc = gcry_cipher_decrypt(h, enc_out, src.size(), src.data(), src.size()); |
122 | 129 | } |
123 | 521 | } |
124 | 644 | gcry_cipher_close(h); |
125 | | |
126 | 644 | gpg_strerror_r(rc, buf_err, sizeof(buf_err)); |
127 | | |
128 | 644 | gpg_strerror_r(static_cast<gcry_error_t>(fuzzed_data.ConsumeIntegral<u_int16_t>()), buf_err, sizeof(buf_err)); |
129 | | |
130 | 644 | ndpi_free(enc_out); |
131 | | |
132 | 644 | return 0; |
133 | 667 | } |