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