/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 |