Skip to content

Commit b3a61bd

Browse files
committed
Merge bitcoin/bitcoin#28074: fuzz: wallet, add target for Crypter
d7290d6 fuzz: wallet, add target for Crypter (Ayush Singh) Pull request description: This PR adds fuzz coverage for `wallet/crypter`. Motivation: Issue [27272](bitcoin/bitcoin#27272 (comment)) I ran this for a long time with Sanitizers on and had no crashes; the average `exec/sec` also looks good to me. However, I would really appreciate it if some of the reviewers could try it on their machines too, and give their feedback. ACKs for top commit: maflcko: utACK d7290d6 achow101: ACK d7290d6 brunoerg: utACK d7290d6 Tree-SHA512: f5c496cabdd3263a7e1ad49eeff702725336f76bf19a82e5dbbead082e990889dd43c851d0d2d6ab740f44b8ec2aa06defd9ff6b02be68b5f8b4eaf963f88599
2 parents 55cf34a + d7290d6 commit b3a61bd

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

src/Makefile.test.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ endif
203203
FUZZ_WALLET_SRC = \
204204
wallet/test/fuzz/coincontrol.cpp \
205205
wallet/test/fuzz/coinselection.cpp \
206+
wallet/test/fuzz/crypter.cpp \
206207
wallet/test/fuzz/fees.cpp \
207208
wallet/test/fuzz/parse_iso8601.cpp \
208209
wallet/test/fuzz/wallet_bdb_parser.cpp

src/wallet/test/fuzz/crypter.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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

Comments
 (0)