Branch data Line data Source code
# 1 : : // Copyright (c) 2009-2020 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 : 55 : {
# 49 : 55 : READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters);
# 50 : 55 : }
# 51 : :
# 52 : : CMasterKey()
# 53 : 106 : {
# 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 : 106 : nDeriveIterations = 25000;
# 57 : 106 : nDerivationMethod = 0;
# 58 : 106 : vchOtherDerivationParameters = std::vector<unsigned char>(0);
# 59 : 106 : }
# 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 : : void CleanKey()
# 87 : 6665 : {
# 88 : 6665 : memory_cleanse(vchKey.data(), vchKey.size());
# 89 : 6665 : memory_cleanse(vchIV.data(), vchIV.size());
# 90 : 6665 : fKeySet = false;
# 91 : 6665 : }
# 92 : :
# 93 : : CCrypter()
# 94 : 6665 : {
# 95 : 6665 : fKeySet = false;
# 96 : 6665 : vchKey.resize(WALLET_CRYPTO_KEY_SIZE);
# 97 : 6665 : vchIV.resize(WALLET_CRYPTO_IV_SIZE);
# 98 : 6665 : }
# 99 : :
# 100 : : ~CCrypter()
# 101 : 6665 : {
# 102 : 6665 : CleanKey();
# 103 : 6665 : }
# 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
|