Line data Source code
1 : // Copyright (c) 2009-2019 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 : const unsigned int WALLET_CRYPTO_KEY_SIZE = 32; 14 : const unsigned int WALLET_CRYPTO_SALT_SIZE = 8; 15 : const unsigned int WALLET_CRYPTO_IV_SIZE = 16; 16 : 17 : /** 18 : * Private key encryption is done based on a CMasterKey, 19 : * which holds a salt and random encryption key. 20 : * 21 : * CMasterKeys are encrypted using AES-256-CBC using a key 22 : * derived using derivation method nDerivationMethod 23 : * (0 == EVP_sha512()) and derivation iterations nDeriveIterations. 24 : * vchOtherDerivationParameters is provided for alternative algorithms 25 : * which may require more parameters (such as scrypt). 26 : * 27 : * Wallet Private Keys are then encrypted using AES-256-CBC 28 : * with the double-sha256 of the public key as the IV, and the 29 : * master key's key as the encryption key (see keystore.[ch]). 30 : */ 31 : 32 : /** Master key for wallet encryption */ 33 145 : class CMasterKey 34 : { 35 : public: 36 : std::vector<unsigned char> vchCryptedKey; 37 : std::vector<unsigned char> vchSalt; 38 : //! 0 = EVP_sha512() 39 : //! 1 = scrypt() 40 : unsigned int nDerivationMethod; 41 : unsigned int nDeriveIterations; 42 : //! Use this for more parameters to key derivation, 43 : //! such as the various parameters to scrypt 44 : std::vector<unsigned char> vchOtherDerivationParameters; 45 : 46 93 : SERIALIZE_METHODS(CMasterKey, obj) 47 : { 48 31 : READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters); 49 31 : } 50 : 51 116 : CMasterKey() 52 58 : { 53 : // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M 54 : // ie slightly lower than the lowest hardware we need bother supporting 55 58 : nDeriveIterations = 25000; 56 58 : nDerivationMethod = 0; 57 58 : vchOtherDerivationParameters = std::vector<unsigned char>(0); 58 116 : } 59 : }; 60 : 61 : typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial; 62 : 63 : namespace wallet_crypto_tests 64 : { 65 : class TestCrypter; 66 : } 67 : 68 : /** Encryption/decryption context with key information */ 69 : class CCrypter 70 : { 71 : friend class wallet_crypto_tests::TestCrypter; // for test access to chKey/chIV 72 : private: 73 : std::vector<unsigned char, secure_allocator<unsigned char>> vchKey; 74 : std::vector<unsigned char, secure_allocator<unsigned char>> vchIV; 75 : bool fKeySet; 76 : 77 : int BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const; 78 : 79 : public: 80 : bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod); 81 : bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) const; 82 : bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext) const; 83 : bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV); 84 : 85 3428 : void CleanKey() 86 : { 87 3428 : memory_cleanse(vchKey.data(), vchKey.size()); 88 3428 : memory_cleanse(vchIV.data(), vchIV.size()); 89 3428 : fKeySet = false; 90 3428 : } 91 : 92 6856 : CCrypter() 93 3428 : { 94 3428 : fKeySet = false; 95 3428 : vchKey.resize(WALLET_CRYPTO_KEY_SIZE); 96 3428 : vchIV.resize(WALLET_CRYPTO_IV_SIZE); 97 6856 : } 98 : 99 6856 : ~CCrypter() 100 3428 : { 101 3428 : CleanKey(); 102 6856 : } 103 : }; 104 : 105 : bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext); 106 : bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext); 107 : bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key); 108 : 109 : #endif // BITCOIN_WALLET_CRYPTER_H