crypter.cpp raw

   1  // Copyright (c) 2022 The Limenka 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 = ConsumeFixedLengthByteVector(fuzzed_data_provider, WALLET_CRYPTO_KEY_SIZE);
  31  
  32      if (fuzzed_data_provider.ConsumeBool()) {
  33          const std::string random_string = fuzzed_data_provider.ConsumeRandomLengthString(100);
  34          SecureString secure_string(random_string.begin(), random_string.end());
  35  
  36          const unsigned int derivation_method = fuzzed_data_provider.ConsumeBool() ? 0 : fuzzed_data_provider.ConsumeIntegral<unsigned int>();
  37  
  38          // Limiting the value of rounds since it is otherwise uselessly expensive and causes a timeout when fuzzing.
  39          crypt.SetKeyFromPassphrase(/*key_data=*/secure_string,
  40                                     /*salt=*/ConsumeFixedLengthByteVector(fuzzed_data_provider, WALLET_CRYPTO_SALT_SIZE),
  41                                     /*rounds=*/fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 25000),
  42                                     /*derivation_method=*/derivation_method);
  43      }
  44  
  45      LIMITED_WHILE(good_data && fuzzed_data_provider.ConsumeBool(), 100)
  46      {
  47          CallOneOf(
  48              fuzzed_data_provider,
  49              [&] {
  50                  const std::vector<unsigned char> random_vector = ConsumeFixedLengthByteVector(fuzzed_data_provider, WALLET_CRYPTO_KEY_SIZE);
  51                  plain_text_ed = CKeyingMaterial(random_vector.begin(), random_vector.end());
  52              },
  53              [&] {
  54                  cipher_text_ed = ConsumeRandomLengthByteVector(fuzzed_data_provider, 64);
  55              },
  56              [&] {
  57                  (void)crypt.Encrypt(plain_text_ed, cipher_text_ed);
  58              },
  59              [&] {
  60                  (void)crypt.Decrypt(cipher_text_ed, plain_text_ed);
  61              },
  62              [&] {
  63                  const CKeyingMaterial master_key(random_key.begin(), random_key.end());
  64                  const uint256 iv = ConsumeUInt256(fuzzed_data_provider);
  65                  (void)EncryptSecret(master_key, plain_text_ed, iv, cipher_text_ed);
  66              },
  67              [&] {
  68                  const CKeyingMaterial master_key(random_key.begin(), random_key.end());
  69                  const uint256 iv = ConsumeUInt256(fuzzed_data_provider);
  70                  (void)DecryptSecret(master_key, cipher_text_ed, iv, plain_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                  const CPubKey pub_key = *random_pub_key;
  79                  const CKeyingMaterial master_key(random_key.begin(), random_key.end());
  80                  const std::vector<unsigned char> crypted_secret = ConsumeRandomLengthByteVector(fuzzed_data_provider, 64);
  81                  CKey key;
  82                  (void)DecryptKey(master_key, crypted_secret, pub_key, key);
  83              });
  84      }
  85  }
  86  } // namespace
  87  } // namespace wallet
  88