Skip to content

Commit 2fc4e59

Browse files
tests: Add fuzzing harness for ChaCha20
1 parent e9e8aac commit 2fc4e59

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

src/Makefile.test.include

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ FUZZ_TARGETS = \
3535
test/fuzz/crypto \
3636
test/fuzz/crypto_aes256 \
3737
test/fuzz/crypto_aes256cbc \
38+
test/fuzz/crypto_chacha20 \
3839
test/fuzz/crypto_common \
3940
test/fuzz/crypto_hkdf_hmac_sha256_l32 \
4041
test/fuzz/crypto_poly1305 \
@@ -502,6 +503,12 @@ test_fuzz_crypto_aes256cbc_LDADD = $(FUZZ_SUITE_LD_COMMON)
502503
test_fuzz_crypto_aes256cbc_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
503504
test_fuzz_crypto_aes256cbc_SOURCES = test/fuzz/crypto_aes256cbc.cpp
504505

506+
test_fuzz_crypto_chacha20_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
507+
test_fuzz_crypto_chacha20_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
508+
test_fuzz_crypto_chacha20_LDADD = $(FUZZ_SUITE_LD_COMMON)
509+
test_fuzz_crypto_chacha20_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
510+
test_fuzz_crypto_chacha20_SOURCES = test/fuzz/crypto_chacha20.cpp
511+
505512
test_fuzz_crypto_common_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
506513
test_fuzz_crypto_common_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
507514
test_fuzz_crypto_common_LDADD = $(FUZZ_SUITE_LD_COMMON)

src/test/fuzz/crypto_chacha20.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) 2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <crypto/chacha20.h>
6+
#include <test/fuzz/FuzzedDataProvider.h>
7+
#include <test/fuzz/fuzz.h>
8+
#include <test/fuzz/util.h>
9+
10+
#include <cstdint>
11+
#include <vector>
12+
13+
void test_one_input(const std::vector<uint8_t>& buffer)
14+
{
15+
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
16+
17+
ChaCha20 chacha20;
18+
if (fuzzed_data_provider.ConsumeBool()) {
19+
const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, fuzzed_data_provider.ConsumeIntegralInRange<size_t>(16, 32));
20+
chacha20 = ChaCha20{key.data(), key.size()};
21+
}
22+
while (fuzzed_data_provider.ConsumeBool()) {
23+
switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 4)) {
24+
case 0: {
25+
const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, fuzzed_data_provider.ConsumeIntegralInRange<size_t>(16, 32));
26+
chacha20.SetKey(key.data(), key.size());
27+
break;
28+
}
29+
case 1: {
30+
chacha20.SetIV(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
31+
break;
32+
}
33+
case 2: {
34+
chacha20.Seek(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
35+
break;
36+
}
37+
case 3: {
38+
std::vector<uint8_t> output(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
39+
chacha20.Keystream(output.data(), output.size());
40+
break;
41+
}
42+
case 4: {
43+
std::vector<uint8_t> output(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
44+
const std::vector<uint8_t> input = ConsumeFixedLengthByteVector(fuzzed_data_provider, output.size());
45+
chacha20.Crypt(input.data(), output.data(), input.size());
46+
break;
47+
}
48+
}
49+
}
50+
}

0 commit comments

Comments
 (0)