Branch data Line data Source code
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 : 0 : SERIALIZE_METHODS(CMasterKey, obj) 48 : : { 49 : 0 : READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters); 50 : 0 : } 51 : : 52 : 0 : CMasterKey() 53 : : { 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(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const; 79 : : 80 : : public: 81 : : bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod); 82 : : bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) const; 83 : : bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext) const; 84 : : bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV); 85 : : 86 : 0 : void CleanKey() 87 : : { 88 : 0 : memory_cleanse(vchKey.data(), vchKey.size()); 89 : 0 : memory_cleanse(vchIV.data(), vchIV.size()); 90 : 0 : fKeySet = false; 91 : 0 : } 92 : : 93 : 0 : CCrypter() 94 : : { 95 : 0 : fKeySet = false; 96 [ # # ]: 0 : vchKey.resize(WALLET_CRYPTO_KEY_SIZE); 97 [ # # ]: 0 : vchIV.resize(WALLET_CRYPTO_IV_SIZE); 98 : 0 : } 99 : : 100 : 0 : ~CCrypter() 101 : : { 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& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext); 108 : : bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key); 109 : : } // namespace wallet 110 : : 111 : : #endif // BITCOIN_WALLET_CRYPTER_H