/ src / wallet / test / fuzz / crypter.cpp
crypter.cpp
 1  // Copyright (c) 2022-present 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      SeedRandomStateForTest(SeedRand::ZEROS);
24      FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
25      bool good_data{true};
26  
27      CCrypter crypt;
28      // These values are regularly updated within `CallOneOf`
29      std::vector<unsigned char> cipher_text_ed;
30      CKeyingMaterial plain_text_ed;
31      const std::vector<unsigned char> random_key = ConsumeFixedLengthByteVector(fuzzed_data_provider, WALLET_CRYPTO_KEY_SIZE);
32  
33      if (fuzzed_data_provider.ConsumeBool()) {
34          const std::string random_string = fuzzed_data_provider.ConsumeRandomLengthString(100);
35          SecureString secure_string(random_string.begin(), random_string.end());
36  
37          const unsigned int derivation_method = fuzzed_data_provider.ConsumeBool() ? 0 : fuzzed_data_provider.ConsumeIntegral<unsigned int>();
38  
39          // Limiting the value of rounds since it is otherwise uselessly expensive and causes a timeout when fuzzing.
40          crypt.SetKeyFromPassphrase(/*key_data=*/secure_string,
41                                     /*salt=*/ConsumeFixedLengthByteVector(fuzzed_data_provider, WALLET_CRYPTO_SALT_SIZE),
42                                     /*rounds=*/fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, CMasterKey::DEFAULT_DERIVE_ITERATIONS),
43                                     /*derivation_method=*/derivation_method);
44      }
45  
46      CKey random_ckey;
47      random_ckey.Set(random_key.begin(), random_key.end(), /*fCompressedIn=*/fuzzed_data_provider.ConsumeBool());
48      if (!random_ckey.IsValid()) return;
49      CPubKey pubkey{random_ckey.GetPubKey()};
50  
51      LIMITED_WHILE(good_data && fuzzed_data_provider.ConsumeBool(), 100)
52      {
53          CallOneOf(
54              fuzzed_data_provider,
55              [&] {
56                  const std::vector<unsigned char> random_vector = ConsumeFixedLengthByteVector(fuzzed_data_provider, WALLET_CRYPTO_KEY_SIZE);
57                  plain_text_ed = CKeyingMaterial(random_vector.begin(), random_vector.end());
58              },
59              [&] {
60                  cipher_text_ed = ConsumeRandomLengthByteVector(fuzzed_data_provider, 64);
61              },
62              [&] {
63                  (void)crypt.Encrypt(plain_text_ed, cipher_text_ed);
64              },
65              [&] {
66                  (void)crypt.Decrypt(cipher_text_ed, plain_text_ed);
67              },
68              [&] {
69                  const CKeyingMaterial master_key(random_key.begin(), random_key.end());;
70                  (void)EncryptSecret(master_key, plain_text_ed, pubkey.GetHash(), cipher_text_ed);
71              },
72              [&] {
73                  std::optional<CPubKey> random_pub_key{ConsumeDeserializable<CPubKey>(fuzzed_data_provider)};
74                  if (!random_pub_key) {
75                      good_data = false;
76                      return;
77                  }
78                  pubkey = *random_pub_key;
79              },
80              [&] {
81                  const CKeyingMaterial master_key(random_key.begin(), random_key.end());
82                  CKey key;
83                  (void)DecryptKey(master_key, cipher_text_ed, pubkey, key);
84              });
85      }
86  }
87  } // namespace
88  } // namespace wallet