You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

crypter.h 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Copyright (c) 2009-2014 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. #ifndef BITCOIN_WALLET_CRYPTER_H
  5. #define BITCOIN_WALLET_CRYPTER_H
  6. #include "keystore.h"
  7. #include "serialize.h"
  8. #include "support/allocators/secure.h"
  9. class uint256;
  10. const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
  11. const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
  12. /**
  13. * Private key encryption is done based on a CMasterKey,
  14. * which holds a salt and random encryption key.
  15. *
  16. * CMasterKeys are encrypted using AES-256-CBC using a key
  17. * derived using derivation method nDerivationMethod
  18. * (0 == EVP_sha512()) and derivation iterations nDeriveIterations.
  19. * vchOtherDerivationParameters is provided for alternative algorithms
  20. * which may require more parameters (such as scrypt).
  21. *
  22. * Wallet Private Keys are then encrypted using AES-256-CBC
  23. * with the double-sha256 of the public key as the IV, and the
  24. * master key's key as the encryption key (see keystore.[ch]).
  25. */
  26. /** Master key for wallet encryption */
  27. class CMasterKey
  28. {
  29. public:
  30. std::vector<unsigned char> vchCryptedKey;
  31. std::vector<unsigned char> vchSalt;
  32. //! 0 = EVP_sha512()
  33. //! 1 = scrypt()
  34. unsigned int nDerivationMethod;
  35. unsigned int nDeriveIterations;
  36. //! Use this for more parameters to key derivation,
  37. //! such as the various parameters to scrypt
  38. std::vector<unsigned char> vchOtherDerivationParameters;
  39. ADD_SERIALIZE_METHODS;
  40. template <typename Stream, typename Operation>
  41. inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
  42. READWRITE(vchCryptedKey);
  43. READWRITE(vchSalt);
  44. READWRITE(nDerivationMethod);
  45. READWRITE(nDeriveIterations);
  46. READWRITE(vchOtherDerivationParameters);
  47. }
  48. CMasterKey()
  49. {
  50. // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
  51. // ie slightly lower than the lowest hardware we need bother supporting
  52. nDeriveIterations = 25000;
  53. nDerivationMethod = 0;
  54. vchOtherDerivationParameters = std::vector<unsigned char>(0);
  55. }
  56. };
  57. typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
  58. /** Encryption/decryption context with key information */
  59. class CCrypter
  60. {
  61. private:
  62. unsigned char chKey[WALLET_CRYPTO_KEY_SIZE];
  63. unsigned char chIV[WALLET_CRYPTO_KEY_SIZE];
  64. bool fKeySet;
  65. public:
  66. bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
  67. bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext);
  68. bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
  69. bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
  70. void CleanKey()
  71. {
  72. memory_cleanse(chKey, sizeof(chKey));
  73. memory_cleanse(chIV, sizeof(chIV));
  74. fKeySet = false;
  75. }
  76. CCrypter()
  77. {
  78. fKeySet = false;
  79. // Try to keep the key data out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap)
  80. // Note that this does nothing about suspend-to-disk (which will put all our key data on disk)
  81. // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process.
  82. LockedPageManager::Instance().LockRange(&chKey[0], sizeof chKey);
  83. LockedPageManager::Instance().LockRange(&chIV[0], sizeof chIV);
  84. }
  85. ~CCrypter()
  86. {
  87. CleanKey();
  88. LockedPageManager::Instance().UnlockRange(&chKey[0], sizeof chKey);
  89. LockedPageManager::Instance().UnlockRange(&chIV[0], sizeof chIV);
  90. }
  91. };
  92. /** Keystore which keeps the private keys encrypted.
  93. * It derives from the basic key store, which is used if no encryption is active.
  94. */
  95. class CCryptoKeyStore : public CBasicKeyStore
  96. {
  97. private:
  98. CryptedKeyMap mapCryptedKeys;
  99. CKeyingMaterial vMasterKey;
  100. //! if fUseCrypto is true, mapKeys must be empty
  101. //! if fUseCrypto is false, vMasterKey must be empty
  102. bool fUseCrypto;
  103. //! keeps track of whether Unlock has run a thorough check before
  104. bool fDecryptionThoroughlyChecked;
  105. protected:
  106. bool SetCrypted();
  107. //! will encrypt previously unencrypted keys
  108. bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
  109. bool Unlock(const CKeyingMaterial& vMasterKeyIn);
  110. public:
  111. CCryptoKeyStore() : fUseCrypto(false), fDecryptionThoroughlyChecked(false)
  112. {
  113. }
  114. bool IsCrypted() const
  115. {
  116. return fUseCrypto;
  117. }
  118. bool IsLocked() const
  119. {
  120. if (!IsCrypted())
  121. return false;
  122. bool result;
  123. {
  124. LOCK(cs_KeyStore);
  125. result = vMasterKey.empty();
  126. }
  127. return result;
  128. }
  129. bool Lock();
  130. virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
  131. bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
  132. bool HaveKey(const CKeyID &address) const
  133. {
  134. {
  135. LOCK(cs_KeyStore);
  136. if (!IsCrypted())
  137. return CBasicKeyStore::HaveKey(address);
  138. return mapCryptedKeys.count(address) > 0;
  139. }
  140. return false;
  141. }
  142. bool GetKey(const CKeyID &address, CKey& keyOut) const;
  143. bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
  144. void GetKeys(std::set<CKeyID> &setAddress) const
  145. {
  146. if (!IsCrypted())
  147. {
  148. CBasicKeyStore::GetKeys(setAddress);
  149. return;
  150. }
  151. setAddress.clear();
  152. CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
  153. while (mi != mapCryptedKeys.end())
  154. {
  155. setAddress.insert((*mi).first);
  156. mi++;
  157. }
  158. }
  159. /**
  160. * Wallet status (encrypted, locked) changed.
  161. * Note: Called without locks held.
  162. */
  163. boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
  164. };
  165. #endif // BITCOIN_WALLET_CRYPTER_H