|
| 1 | +// Copyright (c) 2022 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 <test/fuzz/FuzzedDataProvider.h> |
| 6 | +#include <test/fuzz/fuzz.h> |
| 7 | +#include <test/fuzz/util.h> |
| 8 | +#include <test/util/setup_common.h> |
| 9 | +#include <wallet/crypter.h> |
| 10 | + |
| 11 | +namespace wallet { |
| 12 | +namespace { |
| 13 | + |
| 14 | +const TestingSetup* g_setup; |
| 15 | +void initialize_crypter() |
| 16 | +{ |
| 17 | + static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); |
| 18 | + g_setup = testing_setup.get(); |
| 19 | +} |
| 20 | + |
| 21 | +FUZZ_TARGET(crypter, .init = initialize_crypter) |
| 22 | +{ |
| 23 | + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); |
| 24 | + bool good_data{true}; |
| 25 | + |
| 26 | + CCrypter crypt; |
| 27 | + // These values are regularly updated within `CallOneOf` |
| 28 | + std::vector<unsigned char> cipher_text_ed; |
| 29 | + CKeyingMaterial plain_text_ed; |
| 30 | + const std::vector<unsigned char> random_key = ConsumeRandomLengthByteVector(fuzzed_data_provider); |
| 31 | + |
| 32 | + LIMITED_WHILE(good_data && fuzzed_data_provider.ConsumeBool(), 10000) |
| 33 | + { |
| 34 | + CallOneOf( |
| 35 | + fuzzed_data_provider, |
| 36 | + [&] { |
| 37 | + const std::string random_string = fuzzed_data_provider.ConsumeRandomLengthString(); |
| 38 | + SecureString secure_string(random_string.begin(), random_string.end()); |
| 39 | + |
| 40 | + const unsigned int derivation_method = fuzzed_data_provider.ConsumeBool() ? 0 : fuzzed_data_provider.ConsumeIntegral<unsigned int>(); |
| 41 | + |
| 42 | + // Limiting the value of nRounds since it is otherwise uselessly expensive and causes a timeout when fuzzing. |
| 43 | + crypt.SetKeyFromPassphrase(/*strKeyData=*/secure_string, |
| 44 | + /*chSalt=*/ConsumeRandomLengthByteVector(fuzzed_data_provider), |
| 45 | + /*nRounds=*/fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 25000), |
| 46 | + /*nDerivationMethod=*/derivation_method); |
| 47 | + }, |
| 48 | + [&] { |
| 49 | + const std::vector<unsigned char> random_vector = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32); |
| 50 | + const CKeyingMaterial new_key(random_vector.begin(), random_vector.end()); |
| 51 | + const std::vector<unsigned char>& new_IV = ConsumeFixedLengthByteVector(fuzzed_data_provider, 16); |
| 52 | + crypt.SetKey(new_key, new_IV); |
| 53 | + }, |
| 54 | + [&] { |
| 55 | + const std::vector<unsigned char> random_vector = ConsumeRandomLengthByteVector(fuzzed_data_provider); |
| 56 | + plain_text_ed = CKeyingMaterial(random_vector.begin(), random_vector.end()); |
| 57 | + }, |
| 58 | + [&] { |
| 59 | + cipher_text_ed = ConsumeRandomLengthByteVector(fuzzed_data_provider); |
| 60 | + }, |
| 61 | + [&] { |
| 62 | + (void)crypt.Encrypt(plain_text_ed, cipher_text_ed); |
| 63 | + }, |
| 64 | + [&] { |
| 65 | + (void)crypt.Decrypt(cipher_text_ed, plain_text_ed); |
| 66 | + }, |
| 67 | + [&] { |
| 68 | + const CKeyingMaterial master_key(random_key.begin(), random_key.end()); |
| 69 | + const uint256 iv = ConsumeUInt256(fuzzed_data_provider); |
| 70 | + EncryptSecret(master_key, plain_text_ed, iv, cipher_text_ed); |
| 71 | + }, |
| 72 | + [&] { |
| 73 | + const CKeyingMaterial master_key(random_key.begin(), random_key.end()); |
| 74 | + const uint256 iv = ConsumeUInt256(fuzzed_data_provider); |
| 75 | + DecryptSecret(master_key, cipher_text_ed, iv, plain_text_ed); |
| 76 | + }, |
| 77 | + [&] { |
| 78 | + std::optional<CPubKey> random_pub_key = ConsumeDeserializable<CPubKey>(fuzzed_data_provider); |
| 79 | + if (!random_pub_key) { |
| 80 | + good_data = false; |
| 81 | + return; |
| 82 | + } |
| 83 | + const CPubKey pub_key = *random_pub_key; |
| 84 | + const CKeyingMaterial master_key(random_key.begin(), random_key.end()); |
| 85 | + const std::vector<unsigned char> crypted_secret = ConsumeRandomLengthByteVector(fuzzed_data_provider); |
| 86 | + CKey key; |
| 87 | + DecryptKey(master_key, crypted_secret, pub_key, key); |
| 88 | + }); |
| 89 | + } |
| 90 | +} |
| 91 | +} // namespace |
| 92 | +} // namespace wallet |
0 commit comments