/root/bitcoin/src/wallet/test/fuzz/crypter.cpp
| Line | Count | Source | 
| 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 | 0 | { | 
| 17 | 0 |     static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); | 
| 18 | 0 |     g_setup = testing_setup.get(); | 
| 19 | 0 | } | 
| 20 |  |  | 
| 21 |  | FUZZ_TARGET(crypter, .init = initialize_crypter) | 
| 22 | 0 | { | 
| 23 | 0 |     SeedRandomStateForTest(SeedRand::ZEROS); | 
| 24 | 0 |     FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); | 
| 25 | 0 |     bool good_data{true}; | 
| 26 |  | 
 | 
| 27 | 0 |     CCrypter crypt; | 
| 28 |  |     // These values are regularly updated within `CallOneOf` | 
| 29 | 0 |     std::vector<unsigned char> cipher_text_ed; | 
| 30 | 0 |     CKeyingMaterial plain_text_ed; | 
| 31 | 0 |     const std::vector<unsigned char> random_key = ConsumeFixedLengthByteVector(fuzzed_data_provider, WALLET_CRYPTO_KEY_SIZE); | 
| 32 |  | 
 | 
| 33 | 0 |     if (fuzzed_data_provider.ConsumeBool()) { | 
| 34 | 0 |         const std::string random_string = fuzzed_data_provider.ConsumeRandomLengthString(100); | 
| 35 | 0 |         SecureString secure_string(random_string.begin(), random_string.end()); | 
| 36 |  | 
 | 
| 37 | 0 |         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 | 0 |         crypt.SetKeyFromPassphrase(/*key_data=*/secure_string, | 
| 41 | 0 |                                    /*salt=*/ConsumeFixedLengthByteVector(fuzzed_data_provider, WALLET_CRYPTO_SALT_SIZE), | 
| 42 | 0 |                                    /*rounds=*/fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, CMasterKey::DEFAULT_DERIVE_ITERATIONS), | 
| 43 | 0 |                                    /*derivation_method=*/derivation_method); | 
| 44 | 0 |     } | 
| 45 |  | 
 | 
| 46 | 0 |     CKey random_ckey; | 
| 47 | 0 |     random_ckey.Set(random_key.begin(), random_key.end(), /*fCompressedIn=*/fuzzed_data_provider.ConsumeBool()); | 
| 48 | 0 |     if (!random_ckey.IsValid()) return; | 
| 49 | 0 |     CPubKey pubkey{random_ckey.GetPubKey()}; | 
| 50 |  | 
 | 
| 51 | 0 |     LIMITED_WHILE(good_data && fuzzed_data_provider.ConsumeBool(), 100) | 
| 52 | 0 |     { | 
| 53 | 0 |         CallOneOf( | 
| 54 | 0 |             fuzzed_data_provider, | 
| 55 | 0 |             [&] { | 
| 56 | 0 |                 const std::vector<unsigned char> random_vector = ConsumeFixedLengthByteVector(fuzzed_data_provider, WALLET_CRYPTO_KEY_SIZE); | 
| 57 | 0 |                 plain_text_ed = CKeyingMaterial(random_vector.begin(), random_vector.end()); | 
| 58 | 0 |             }, | 
| 59 | 0 |             [&] { | 
| 60 | 0 |                 cipher_text_ed = ConsumeRandomLengthByteVector(fuzzed_data_provider, 64); | 
| 61 | 0 |             }, | 
| 62 | 0 |             [&] { | 
| 63 | 0 |                 (void)crypt.Encrypt(plain_text_ed, cipher_text_ed); | 
| 64 | 0 |             }, | 
| 65 | 0 |             [&] { | 
| 66 | 0 |                 (void)crypt.Decrypt(cipher_text_ed, plain_text_ed); | 
| 67 | 0 |             }, | 
| 68 | 0 |             [&] { | 
| 69 | 0 |                 const CKeyingMaterial master_key(random_key.begin(), random_key.end());; | 
| 70 | 0 |                 (void)EncryptSecret(master_key, plain_text_ed, pubkey.GetHash(), cipher_text_ed); | 
| 71 | 0 |             }, | 
| 72 | 0 |             [&] { | 
| 73 | 0 |                 std::optional<CPubKey> random_pub_key{ConsumeDeserializable<CPubKey>(fuzzed_data_provider)}; | 
| 74 | 0 |                 if (!random_pub_key) { | 
| 75 | 0 |                     good_data = false; | 
| 76 | 0 |                     return; | 
| 77 | 0 |                 } | 
| 78 | 0 |                 pubkey = *random_pub_key; | 
| 79 | 0 |             }, | 
| 80 | 0 |             [&] { | 
| 81 | 0 |                 const CKeyingMaterial master_key(random_key.begin(), random_key.end()); | 
| 82 | 0 |                 CKey key; | 
| 83 | 0 |                 (void)DecryptKey(master_key, cipher_text_ed, pubkey, key); | 
| 84 | 0 |             }); | 
| 85 | 0 |     } | 
| 86 | 0 | } | 
| 87 |  | } // namespace | 
| 88 |  | } // namespace wallet |