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 : : 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 : : 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 : : SERIALIZE_METHODS(CMasterKey, obj)
# 47 : 44 : {
# 48 : 44 : READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters);
# 49 : 44 : }
# 50 : :
# 51 : : CMasterKey()
# 52 : 84 : {
# 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 : 84 : nDeriveIterations = 25000;
# 56 : 84 : nDerivationMethod = 0;
# 57 : 84 : vchOtherDerivationParameters = std::vector<unsigned char>(0);
# 58 : 84 : }
# 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 : : void CleanKey()
# 86 : 7090 : {
# 87 : 7090 : memory_cleanse(vchKey.data(), vchKey.size());
# 88 : 7090 : memory_cleanse(vchIV.data(), vchIV.size());
# 89 : 7090 : fKeySet = false;
# 90 : 7090 : }
# 91 : :
# 92 : : CCrypter()
# 93 : 7090 : {
# 94 : 7090 : fKeySet = false;
# 95 : 7090 : vchKey.resize(WALLET_CRYPTO_KEY_SIZE);
# 96 : 7090 : vchIV.resize(WALLET_CRYPTO_IV_SIZE);
# 97 : 7090 : }
# 98 : :
# 99 : : ~CCrypter()
# 100 : 7090 : {
# 101 : 7090 : CleanKey();
# 102 : 7090 : }
# 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
|