diff --git a/src/test/fuzz/CMakeLists.txt b/src/test/fuzz/CMakeLists.txt --- a/src/test/fuzz/CMakeLists.txt +++ b/src/test/fuzz/CMakeLists.txt @@ -95,7 +95,13 @@ checkqueue coins_view crypto + crypto_aes256 + crypto_aes256cbc + crypto_chacha20 + crypto_chacha20_poly1305_aead crypto_common + crypto_hkdf_hmac_sha256_l32 + crypto_poly1305 cuckoocache descriptor_parse eval_script diff --git a/src/test/fuzz/crypto_aes256.cpp b/src/test/fuzz/crypto_aes256.cpp new file mode 100644 --- /dev/null +++ b/src/test/fuzz/crypto_aes256.cpp @@ -0,0 +1,31 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include + +#include +#include +#include + +void test_one_input(const std::vector &buffer) { + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + const std::vector key = + ConsumeFixedLengthByteVector(fuzzed_data_provider, AES256_KEYSIZE); + + AES256Encrypt encrypt{key.data()}; + AES256Decrypt decrypt{key.data()}; + + while (fuzzed_data_provider.ConsumeBool()) { + const std::vector plaintext = + ConsumeFixedLengthByteVector(fuzzed_data_provider, AES_BLOCKSIZE); + std::vector ciphertext(AES_BLOCKSIZE); + encrypt.Encrypt(ciphertext.data(), plaintext.data()); + std::vector decrypted_plaintext(AES_BLOCKSIZE); + decrypt.Decrypt(decrypted_plaintext.data(), ciphertext.data()); + assert(decrypted_plaintext == plaintext); + } +} diff --git a/src/test/fuzz/crypto_aes256cbc.cpp b/src/test/fuzz/crypto_aes256cbc.cpp new file mode 100644 --- /dev/null +++ b/src/test/fuzz/crypto_aes256cbc.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include + +#include +#include +#include + +void test_one_input(const std::vector &buffer) { + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + const std::vector key = + ConsumeFixedLengthByteVector(fuzzed_data_provider, AES256_KEYSIZE); + const std::vector iv = + ConsumeFixedLengthByteVector(fuzzed_data_provider, AES_BLOCKSIZE); + const bool pad = fuzzed_data_provider.ConsumeBool(); + + AES256CBCEncrypt encrypt{key.data(), iv.data(), pad}; + AES256CBCDecrypt decrypt{key.data(), iv.data(), pad}; + + while (fuzzed_data_provider.ConsumeBool()) { + const std::vector plaintext = + ConsumeRandomLengthByteVector(fuzzed_data_provider); + std::vector ciphertext(plaintext.size() + AES_BLOCKSIZE); + const int encrypt_ret = encrypt.Encrypt( + plaintext.data(), plaintext.size(), ciphertext.data()); + ciphertext.resize(encrypt_ret); + std::vector decrypted_plaintext(ciphertext.size()); + const int decrypt_ret = decrypt.Decrypt( + ciphertext.data(), ciphertext.size(), decrypted_plaintext.data()); + decrypted_plaintext.resize(decrypt_ret); + assert(decrypted_plaintext == plaintext || + (!pad && plaintext.size() % AES_BLOCKSIZE != 0 && + encrypt_ret == 0 && decrypt_ret == 0)); + } +} diff --git a/src/test/fuzz/crypto_chacha20.cpp b/src/test/fuzz/crypto_chacha20.cpp new file mode 100644 --- /dev/null +++ b/src/test/fuzz/crypto_chacha20.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include + +#include +#include + +void test_one_input(const std::vector &buffer) { + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + + ChaCha20 chacha20; + if (fuzzed_data_provider.ConsumeBool()) { + const std::vector key = ConsumeFixedLengthByteVector( + fuzzed_data_provider, + fuzzed_data_provider.ConsumeIntegralInRange(16, 32)); + chacha20 = ChaCha20{key.data(), key.size()}; + } + while (fuzzed_data_provider.ConsumeBool()) { + switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 4)) { + case 0: { + const std::vector key = ConsumeFixedLengthByteVector( + fuzzed_data_provider, + fuzzed_data_provider.ConsumeIntegralInRange(16, + 32)); + chacha20.SetKey(key.data(), key.size()); + break; + } + case 1: { + chacha20.SetIV( + fuzzed_data_provider.ConsumeIntegral()); + break; + } + case 2: { + chacha20.Seek(fuzzed_data_provider.ConsumeIntegral()); + break; + } + case 3: { + std::vector output( + fuzzed_data_provider.ConsumeIntegralInRange(0, + 4096)); + chacha20.Keystream(output.data(), output.size()); + break; + } + case 4: { + std::vector output( + fuzzed_data_provider.ConsumeIntegralInRange(0, + 4096)); + const std::vector input = ConsumeFixedLengthByteVector( + fuzzed_data_provider, output.size()); + chacha20.Crypt(input.data(), output.data(), input.size()); + break; + } + } + } +} diff --git a/src/test/fuzz/crypto_chacha20_poly1305_aead.cpp b/src/test/fuzz/crypto_chacha20_poly1305_aead.cpp new file mode 100644 --- /dev/null +++ b/src/test/fuzz/crypto_chacha20_poly1305_aead.cpp @@ -0,0 +1,88 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +void test_one_input(const std::vector &buffer) { + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + + const std::vector k1 = ConsumeFixedLengthByteVector( + fuzzed_data_provider, CHACHA20_POLY1305_AEAD_KEY_LEN); + const std::vector k2 = ConsumeFixedLengthByteVector( + fuzzed_data_provider, CHACHA20_POLY1305_AEAD_KEY_LEN); + + ChaCha20Poly1305AEAD aead(k1.data(), k1.size(), k2.data(), k2.size()); + uint64_t seqnr_payload = 0; + uint64_t seqnr_aad = 0; + int aad_pos = 0; + size_t buffer_size = + fuzzed_data_provider.ConsumeIntegralInRange(0, 4096); + std::vector in( + buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0); + std::vector out( + buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0); + bool is_encrypt = fuzzed_data_provider.ConsumeBool(); + while (fuzzed_data_provider.ConsumeBool()) { + switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 6)) { + case 0: { + buffer_size = + fuzzed_data_provider.ConsumeIntegralInRange(64, + 4096); + in = std::vector(buffer_size + + CHACHA20_POLY1305_AEAD_AAD_LEN + + POLY1305_TAGLEN, + 0); + out = std::vector(buffer_size + + CHACHA20_POLY1305_AEAD_AAD_LEN + + POLY1305_TAGLEN, + 0); + break; + } + case 1: { + (void)aead.Crypt(seqnr_payload, seqnr_aad, aad_pos, out.data(), + out.size(), in.data(), buffer_size, + is_encrypt); + break; + } + case 2: { + uint32_t len = 0; + const bool ok = + aead.GetLength(&len, seqnr_aad, aad_pos, in.data()); + assert(ok); + break; + } + case 3: { + seqnr_payload += 1; + aad_pos += CHACHA20_POLY1305_AEAD_AAD_LEN; + if (aad_pos + CHACHA20_POLY1305_AEAD_AAD_LEN > + CHACHA20_ROUND_OUTPUT) { + aad_pos = 0; + seqnr_aad += 1; + } + break; + } + case 4: { + seqnr_payload = fuzzed_data_provider.ConsumeIntegral(); + break; + } + case 5: { + seqnr_aad = fuzzed_data_provider.ConsumeIntegral(); + break; + } + case 6: { + is_encrypt = fuzzed_data_provider.ConsumeBool(); + break; + } + } + } +} diff --git a/src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp b/src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp new file mode 100644 --- /dev/null +++ b/src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include + +#include +#include +#include + +void test_one_input(const std::vector &buffer) { + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + + const std::vector initial_key_material = + ConsumeRandomLengthByteVector(fuzzed_data_provider); + + CHKDF_HMAC_SHA256_L32 hkdf_hmac_sha256_l32( + initial_key_material.data(), initial_key_material.size(), + fuzzed_data_provider.ConsumeRandomLengthString(1024)); + while (fuzzed_data_provider.ConsumeBool()) { + std::vector out(32); + hkdf_hmac_sha256_l32.Expand32( + fuzzed_data_provider.ConsumeRandomLengthString(128), out.data()); + } +} diff --git a/src/test/fuzz/crypto_poly1305.cpp b/src/test/fuzz/crypto_poly1305.cpp new file mode 100644 --- /dev/null +++ b/src/test/fuzz/crypto_poly1305.cpp @@ -0,0 +1,23 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include + +#include +#include + +void test_one_input(const std::vector &buffer) { + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + + const std::vector key = + ConsumeFixedLengthByteVector(fuzzed_data_provider, POLY1305_KEYLEN); + const std::vector in = + ConsumeRandomLengthByteVector(fuzzed_data_provider); + + std::vector tag_out(POLY1305_TAGLEN); + poly1305_auth(tag_out.data(), in.data(), in.size(), key.data()); +}