fuzz coverage

Coverage Report

Created: 2025-06-01 19:34

/Users/eugenesiegel/btc/bitcoin/src/wallet/crypter.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2009-2021 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
#ifndef BITCOIN_WALLET_CRYPTER_H
6
#define BITCOIN_WALLET_CRYPTER_H
7
8
#include <serialize.h>
9
#include <support/allocators/secure.h>
10
#include <script/signingprovider.h>
11
12
13
namespace wallet {
14
const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
15
const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
16
const unsigned int WALLET_CRYPTO_IV_SIZE = 16;
17
18
/**
19
 * Private key encryption is done based on a CMasterKey,
20
 * which holds a salt and random encryption key.
21
 *
22
 * CMasterKeys are encrypted using AES-256-CBC using a key
23
 * derived using derivation method nDerivationMethod
24
 * (0 == EVP_sha512()) and derivation iterations nDeriveIterations.
25
 * vchOtherDerivationParameters is provided for alternative algorithms
26
 * which may require more parameters.
27
 *
28
 * Wallet Private Keys are then encrypted using AES-256-CBC
29
 * with the double-sha256 of the public key as the IV, and the
30
 * master key's key as the encryption key (see keystore.[ch]).
31
 */
32
33
/** Master key for wallet encryption */
34
class CMasterKey
35
{
36
public:
37
    std::vector<unsigned char> vchCryptedKey;
38
    std::vector<unsigned char> vchSalt;
39
    //! 0 = EVP_sha512()
40
    unsigned int nDerivationMethod;
41
    unsigned int nDeriveIterations;
42
    //! Use this for more parameters to key derivation (currently unused)
43
    std::vector<unsigned char> vchOtherDerivationParameters;
44
45
    //! Default/minimum number of key derivation rounds
46
    // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
47
    // ie slightly lower than the lowest hardware we need bother supporting
48
    static constexpr unsigned int DEFAULT_DERIVE_ITERATIONS = 25000;
49
50
    SERIALIZE_METHODS(CMasterKey, obj)
51
0
    {
52
0
        READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters);
Line
Count
Source
156
0
#define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__))
        READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters);
Line
Count
Source
156
0
#define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__))
53
0
    }
Unexecuted instantiation: _ZN6wallet10CMasterKey16SerializationOpsI10DataStreamKS0_15ActionSerializeEEvRT0_RT_T1_
Unexecuted instantiation: _ZN6wallet10CMasterKey16SerializationOpsI10DataStreamS0_17ActionUnserializeEEvRT0_RT_T1_
54
55
    CMasterKey()
56
0
    {
57
0
        nDeriveIterations = DEFAULT_DERIVE_ITERATIONS;
58
0
        nDerivationMethod = 0;
59
0
        vchOtherDerivationParameters = std::vector<unsigned char>(0);
60
0
    }
61
};
62
63
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
64
65
namespace wallet_crypto_tests
66
{
67
    class TestCrypter;
68
}
69
70
/** Encryption/decryption context with key information */
71
class CCrypter
72
{
73
friend class wallet_crypto_tests::TestCrypter; // for test access to chKey/chIV
74
private:
75
    std::vector<unsigned char, secure_allocator<unsigned char>> vchKey;
76
    std::vector<unsigned char, secure_allocator<unsigned char>> vchIV;
77
    bool fKeySet;
78
79
    int BytesToKeySHA512AES(std::span<const unsigned char> salt, const SecureString& key_data, int count, unsigned char* key, unsigned char* iv) const;
80
81
public:
82
    bool SetKeyFromPassphrase(const SecureString& key_data, std::span<const unsigned char> salt, const unsigned int rounds, const unsigned int derivation_method);
83
    bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) const;
84
    bool Decrypt(std::span<const unsigned char> ciphertext, CKeyingMaterial& plaintext) const;
85
    bool SetKey(const CKeyingMaterial& new_key, std::span<const unsigned char> new_iv);
86
87
    void CleanKey()
88
0
    {
89
0
        memory_cleanse(vchKey.data(), vchKey.size());
90
0
        memory_cleanse(vchIV.data(), vchIV.size());
91
0
        fKeySet = false;
92
0
    }
93
94
    CCrypter()
95
0
    {
96
0
        fKeySet = false;
97
0
        vchKey.resize(WALLET_CRYPTO_KEY_SIZE);
98
0
        vchIV.resize(WALLET_CRYPTO_IV_SIZE);
99
0
    }
100
101
    ~CCrypter()
102
0
    {
103
0
        CleanKey();
104
0
    }
105
};
106
107
bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
108
bool DecryptSecret(const CKeyingMaterial& master_key, std::span<const unsigned char> ciphertext, const uint256& iv, CKeyingMaterial& plaintext);
109
bool DecryptKey(const CKeyingMaterial& master_key, std::span<const unsigned char> crypted_secret, const CPubKey& pub_key, CKey& key);
110
} // namespace wallet
111
112
#endif // BITCOIN_WALLET_CRYPTER_H