/Users/mcomp/contrib/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 (such as scrypt). |
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 | | //! 1 = scrypt() |
41 | | unsigned int nDerivationMethod; |
42 | | unsigned int nDeriveIterations; |
43 | | //! Use this for more parameters to key derivation, |
44 | | //! such as the various parameters to scrypt |
45 | | std::vector<unsigned char> vchOtherDerivationParameters; |
46 | | |
47 | | SERIALIZE_METHODS(CMasterKey, obj) |
48 | 0 | { |
49 | 0 | READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters); |
50 | 0 | } Unexecuted instantiation: _ZN6wallet10CMasterKey16SerializationOpsI10DataStreamKS0_15ActionSerializeEEvRT0_RT_T1_ Unexecuted instantiation: _ZN6wallet10CMasterKey16SerializationOpsI10DataStreamS0_17ActionUnserializeEEvRT0_RT_T1_ |
51 | | |
52 | | CMasterKey() |
53 | 0 | { |
54 | | // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M |
55 | | // ie slightly lower than the lowest hardware we need bother supporting |
56 | 0 | nDeriveIterations = 25000; |
57 | 0 | nDerivationMethod = 0; |
58 | 0 | vchOtherDerivationParameters = std::vector<unsigned char>(0); |
59 | 0 | } |
60 | | }; |
61 | | |
62 | | typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial; |
63 | | |
64 | | namespace wallet_crypto_tests |
65 | | { |
66 | | class TestCrypter; |
67 | | } |
68 | | |
69 | | /** Encryption/decryption context with key information */ |
70 | | class CCrypter |
71 | | { |
72 | | friend class wallet_crypto_tests::TestCrypter; // for test access to chKey/chIV |
73 | | private: |
74 | | std::vector<unsigned char, secure_allocator<unsigned char>> vchKey; |
75 | | std::vector<unsigned char, secure_allocator<unsigned char>> vchIV; |
76 | | bool fKeySet; |
77 | | |
78 | | int BytesToKeySHA512AES(std::span<const unsigned char> salt, const SecureString& key_data, int count, unsigned char* key, unsigned char* iv) const; |
79 | | |
80 | | public: |
81 | | bool SetKeyFromPassphrase(const SecureString& key_data, std::span<const unsigned char> salt, const unsigned int rounds, const unsigned int derivation_method); |
82 | | bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) const; |
83 | | bool Decrypt(std::span<const unsigned char> ciphertext, CKeyingMaterial& plaintext) const; |
84 | | bool SetKey(const CKeyingMaterial& new_key, std::span<const unsigned char> new_iv); |
85 | | |
86 | | void CleanKey() |
87 | 0 | { |
88 | 0 | memory_cleanse(vchKey.data(), vchKey.size()); |
89 | 0 | memory_cleanse(vchIV.data(), vchIV.size()); |
90 | 0 | fKeySet = false; |
91 | 0 | } |
92 | | |
93 | | CCrypter() |
94 | 0 | { |
95 | 0 | fKeySet = false; |
96 | 0 | vchKey.resize(WALLET_CRYPTO_KEY_SIZE); |
97 | 0 | vchIV.resize(WALLET_CRYPTO_IV_SIZE); |
98 | 0 | } |
99 | | |
100 | | ~CCrypter() |
101 | 0 | { |
102 | 0 | CleanKey(); |
103 | 0 | } |
104 | | }; |
105 | | |
106 | | bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext); |
107 | | bool DecryptSecret(const CKeyingMaterial& master_key, std::span<const unsigned char> ciphertext, const uint256& iv, CKeyingMaterial& plaintext); |
108 | | bool DecryptKey(const CKeyingMaterial& master_key, std::span<const unsigned char> crypted_secret, const CPubKey& pub_key, CKey& key); |
109 | | } // namespace wallet |
110 | | |
111 | | #endif // BITCOIN_WALLET_CRYPTER_H |