LCOV - code coverage report
Current view: top level - src - crypter.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 28 28 100.0 %
Date: 2025-02-23 09:33:43 Functions: 5 5 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2014 The Bitcoin developers
       2             : // Copyright (c) 2017-2021 The PIVX Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #ifndef PIVX_CRYPTER_H
       7             : #define PIVX_CRYPTER_H
       8             : 
       9             : #include "keystore.h"
      10             : #include "serialize.h"
      11             : #include "streams.h"
      12             : #include "support/allocators/zeroafterfree.h"
      13             : 
      14             : class uint256;
      15             : 
      16             : #include <atomic>
      17             : 
      18             : const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
      19             : const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
      20             : const unsigned int WALLET_CRYPTO_IV_SIZE = 16;
      21             : 
      22             : /**
      23             :  * Private key encryption is done based on a CMasterKey,
      24             :  * which holds a salt and random encryption key.
      25             :  *
      26             :  * CMasterKeys are encrypted using AES-256-CBC using a key
      27             :  * derived using derivation method nDerivationMethod
      28             :  * (0 == EVP_sha512()) and derivation iterations nDeriveIterations.
      29             :  * vchOtherDerivationParameters is provided for alternative algorithms
      30             :  * which may require more parameters (such as scrypt).
      31             :  *
      32             :  * Wallet Private Keys are then encrypted using AES-256-CBC
      33             :  * with the double-sha256 of the public key as the IV, and the
      34             :  * master key's key as the encryption key (see keystore.[ch]).
      35             :  */
      36             : 
      37             : /** Master key for wallet encryption */
      38             : class CMasterKey
      39             : {
      40             : public:
      41             :     std::vector<unsigned char> vchCryptedKey;
      42             :     std::vector<unsigned char> vchSalt;
      43             :     //! 0 = EVP_sha512()
      44             :     //! 1 = scrypt()
      45             :     unsigned int nDerivationMethod;
      46             :     unsigned int nDeriveIterations;
      47             :     //! Use this for more parameters to key derivation,
      48             :     //! such as the various parameters to scrypt
      49             :     std::vector<unsigned char> vchOtherDerivationParameters;
      50             : 
      51           9 :     SERIALIZE_METHODS(CMasterKey, obj) { READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters); }
      52             : 
      53          16 :     CMasterKey()
      54          16 :     {
      55             :         // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
      56             :         // ie slightly lower than the lowest hardware we need bother supporting
      57          16 :         nDeriveIterations = 25000;
      58          16 :         nDerivationMethod = 0;
      59          16 :         vchOtherDerivationParameters = std::vector<unsigned char>(0);
      60          16 :     }
      61             : };
      62             : 
      63             : typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
      64             : 
      65             : namespace wallet_crypto
      66             : {
      67             :     class TestCrypter;
      68             : }
      69             : 
      70         430 : class CSecureDataStream : public CBaseDataStream<CKeyingMaterial>
      71             : {
      72             : public:
      73         104 :     explicit CSecureDataStream(int nTypeIn, int nVersionIn) : CBaseDataStream(nTypeIn, nVersionIn) { }
      74             : 
      75             :     CSecureDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) :
      76             :             CBaseDataStream(pbegin, pend, nTypeIn, nVersionIn) { }
      77             : 
      78         111 :     CSecureDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) :
      79         111 :             CBaseDataStream(vchIn, nTypeIn, nVersionIn) { }
      80             : };
      81             : 
      82             : /** Encryption/decryption context with key information */
      83             : class CCrypter
      84             : {
      85             : friend class wallet_crypto::TestCrypter; // for test access to chKey/chIV
      86             : private:
      87             :     std::vector<unsigned char, secure_allocator<unsigned char>> vchKey;
      88             :     std::vector<unsigned char, secure_allocator<unsigned char>> vchIV;
      89             :     bool fKeySet;
      90             : 
      91             :     int BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const;
      92             : 
      93             : public:
      94             :     bool SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
      95             :     bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char>& vchCiphertext) const;
      96             :     bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext) const;
      97             :     bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
      98             : 
      99        5102 :     void CleanKey()
     100             :     {
     101        5102 :         memory_cleanse(vchKey.data(), vchKey.size());
     102        5102 :         memory_cleanse(vchIV.data(), vchIV.size());
     103        5102 :         fKeySet = false;
     104        5102 :     }
     105             : 
     106        5102 :     CCrypter()
     107        5102 :     {
     108        5102 :         fKeySet = false;
     109        5102 :         vchKey.resize(WALLET_CRYPTO_KEY_SIZE);
     110        5102 :         vchIV.resize(WALLET_CRYPTO_IV_SIZE);
     111        5102 :     }
     112             : 
     113        5102 :     ~CCrypter()
     114       10204 :     {
     115        5102 :         CleanKey();
     116        5102 :     }
     117             : };
     118             : 
     119             : bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial& vchPlaintext, const uint256& nIV, std::vector<unsigned char>& vchCiphertext);
     120             : bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
     121             : 
     122             : 
     123             : /** Keystore which keeps the private keys encrypted.
     124             :  * It derives from the basic key store, which is used if no encryption is active.
     125             :  */
     126             : class CCryptoKeyStore : public CBasicKeyStore
     127             : {
     128             : private:
     129             :     //! if fUseCrypto is true, mapKeys and mapSaplingSpendingKeys must be empty
     130             :     //! if fUseCrypto is false, vMasterKey must be empty
     131             :     std::atomic<bool> fUseCrypto;
     132             : 
     133             : protected:
     134             :     // TODO: In the future, move this variable to the wallet class directly following upstream's structure.
     135             :     CKeyingMaterial vMasterKey;
     136             :     // Sapling
     137             :     CryptedSaplingSpendingKeyMap mapCryptedSaplingSpendingKeys;
     138             : 
     139             :     bool SetCrypted();
     140             : 
     141             :     //! will encrypt previously unencrypted keys
     142             :     bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
     143             : 
     144             :     CryptedKeyMap mapCryptedKeys;
     145             : 
     146             :     static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key);
     147             : 
     148             :     // Unlock Sapling keys
     149             :     bool UnlockSaplingKeys(const CKeyingMaterial& vMasterKeyIn, bool fDecryptionThoroughlyChecked);
     150             : 
     151             : public:
     152         505 :     CCryptoKeyStore() : fUseCrypto(false) { }
     153             : 
     154    14437523 :     bool IsCrypted() const { return fUseCrypto; }
     155             :     bool IsLocked() const;
     156             : 
     157             :     virtual bool AddCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret);
     158             :     bool AddKeyPubKey(const CKey& key, const CPubKey& pubkey) override;
     159             :     bool HaveKey(const CKeyID& address) const override;
     160             : 
     161             :     bool GetKey(const CKeyID& address, CKey& keyOut) const override;
     162             :     bool GetPubKey(const CKeyID& address, CPubKey& vchPubKeyOut) const override;
     163             :     std::set<CKeyID> GetKeys() const override;
     164             : 
     165             :     //! Sapling
     166             :     virtual bool AddCryptedSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey& extfvk,
     167             :                                               const std::vector<unsigned char>& vchCryptedSecret);
     168             :     bool HaveSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey& extfvk) const override;
     169             :     bool GetSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey& extfvk, libzcash::SaplingExtendedSpendingKey& skOut) const override;
     170             : 
     171             :     /**
     172             :      * Wallet status (encrypted, locked) changed.
     173             :      * Note: Called without locks held.
     174             :      */
     175             :     boost::signals2::signal<void(CCryptoKeyStore* wallet)> NotifyStatusChanged;
     176             : };
     177             : 
     178             : #endif // PIVX_CRYPTER_H

Generated by: LCOV version 1.14