Anoncoin  0.9.4
P2P Digital Currency
crypter.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2013 The Bitcoin developers
2 // Copyright (c) 2013-2014 The Anoncoin Core developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #ifndef __CRYPTER_H__
7 #define __CRYPTER_H__
8 
9 #include "allocators.h"
10 #include "serialize.h"
11 #include "keystore.h"
12 
13 class uint256;
14 
15 const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
16 const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
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 
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 
48  (
49  READWRITE(vchCryptedKey);
50  READWRITE(vchSalt);
51  READWRITE(nDerivationMethod);
52  READWRITE(nDeriveIterations);
53  READWRITE(vchOtherDerivationParameters);
54  )
55  CMasterKey()
56  {
57  // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
58  // ie slightly lower than the lowest hardware we need bother supporting
59  nDeriveIterations = 25000;
60  nDerivationMethod = 0;
61  vchOtherDerivationParameters = std::vector<unsigned char>(0);
62  }
63 };
64 
65 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
66 
68 class CCrypter
69 {
70 private:
71  unsigned char chKey[WALLET_CRYPTO_KEY_SIZE];
72  unsigned char chIV[WALLET_CRYPTO_KEY_SIZE];
73  bool fKeySet;
74 
75 public:
76  bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
77  bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext);
78  bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
79  bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
80 
81  void CleanKey()
82  {
83  OPENSSL_cleanse(chKey, sizeof(chKey));
84  OPENSSL_cleanse(chIV, sizeof(chIV));
85  fKeySet = false;
86  }
87 
89  {
90  fKeySet = false;
91 
92  // 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)
93  // Note that this does nothing about suspend-to-disk (which will put all our key data on disk)
94  // 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.
95  LockedPageManager::Instance().LockRange(&chKey[0], sizeof chKey);
96  LockedPageManager::Instance().LockRange(&chIV[0], sizeof chIV);
97  }
98 
100  {
101  CleanKey();
102 
103  LockedPageManager::Instance().UnlockRange(&chKey[0], sizeof chKey);
104  LockedPageManager::Instance().UnlockRange(&chIV[0], sizeof chIV);
105  }
106 };
107 
108 bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
109 bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
110 
115 {
116 private:
118 
119  CKeyingMaterial vMasterKey;
120 
121  // if fUseCrypto is true, mapKeys must be empty
122  // if fUseCrypto is false, vMasterKey must be empty
124 
125 protected:
126  bool SetCrypted();
127 
128  // will encrypt previously unencrypted keys
129  bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
130 
131  bool Unlock(const CKeyingMaterial& vMasterKeyIn);
132 
133 public:
134  CCryptoKeyStore() : fUseCrypto(false)
135  {
136  }
137 
138  bool IsCrypted() const
139  {
140  return fUseCrypto;
141  }
142 
143  bool IsLocked() const
144  {
145  if (!IsCrypted())
146  return false;
147  bool result;
148  {
149  LOCK(cs_KeyStore);
150  result = vMasterKey.empty();
151  }
152  return result;
153  }
154 
155  bool Lock();
156 
157  virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
158  bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
159  bool HaveKey(const CKeyID &address) const
160  {
161  {
162  LOCK(cs_KeyStore);
163  if (!IsCrypted())
164  return CBasicKeyStore::HaveKey(address);
165  return mapCryptedKeys.count(address) > 0;
166  }
167  return false;
168  }
169  bool GetKey(const CKeyID &address, CKey& keyOut) const;
170  bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
171  void GetKeys(std::set<CKeyID> &setAddress) const
172  {
173  if (!IsCrypted())
174  {
175  CBasicKeyStore::GetKeys(setAddress);
176  return;
177  }
178  setAddress.clear();
179  CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
180  while (mi != mapCryptedKeys.end())
181  {
182  setAddress.insert((*mi).first);
183  mi++;
184  }
185  }
186 
187  /* Wallet status (encrypted, locked) changed.
188  * Note: Called without locks held.
189  */
190  boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
191 };
192 
193 #endif
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector< unsigned char > &chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
Definition: crypter.cpp:16
bool IsCrypted() const
Definition: crypter.h:138
unsigned int nDerivationMethod
Definition: crypter.h:41
CCriticalSection cs_KeyStore
Definition: keystore.h:31
bool HaveKey(const CKeyID &address) const
Definition: crypter.h:159
bool Encrypt(const CKeyingMaterial &vchPlaintext, std::vector< unsigned char > &vchCiphertext)
Definition: crypter.cpp:49
const unsigned int WALLET_CRYPTO_KEY_SIZE
Definition: crypter.h:15
#define READWRITE(obj)
Definition: serialize.h:101
void LockRange(void *p, size_t size)
Definition: allocators.h:47
unsigned char chIV[WALLET_CRYPTO_KEY_SIZE]
Definition: crypter.h:72
bool SetKey(const CKeyingMaterial &chNewKey, const std::vector< unsigned char > &chNewIV)
Definition: crypter.cpp:37
Encryption/decryption context with key information.
Definition: crypter.h:68
void GetKeys(std::set< CKeyID > &setAddress) const
Definition: keystore.h:81
std::vector< unsigned char > vchCryptedKey
Definition: crypter.h:37
bool HaveKey(const CKeyID &address) const
Definition: keystore.h:72
Master key for wallet encryption.
Definition: crypter.h:34
bool SetCrypted()
Definition: crypter.cpp:124
std::vector< unsigned char > vchOtherDerivationParameters
Definition: crypter.h:45
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
Definition: crypter.h:65
void CleanKey()
Definition: crypter.h:81
bool DecryptSecret(const CKeyingMaterial &vMasterKey, const std::vector< unsigned char > &vchCiphertext, const uint256 &nIV, CKeyingMaterial &vchPlaintext)
Definition: crypter.cpp:114
std::map< CKeyID, std::pair< CPubKey, std::vector< unsigned char > > > CryptedKeyMap
Definition: keystore.h:118
bool EncryptKeys(CKeyingMaterial &vMasterKeyIn)
Definition: crypter.cpp:253
bool IsLocked() const
Definition: crypter.h:143
IMPLEMENT_SERIALIZE(READWRITE(vchCryptedKey);READWRITE(vchSalt);READWRITE(nDerivationMethod);READWRITE(nDeriveIterations);READWRITE(vchOtherDerivationParameters);) CMasterKey()
Definition: crypter.h:48
CKeyingMaterial vMasterKey
Definition: crypter.h:119
virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Definition: crypter.cpp:200
Keystore which keeps the private keys encrypted.
Definition: crypter.h:114
bool GetKey(const CKeyID &address, CKey &keyOut) const
Definition: crypter.cpp:212
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
Definition: crypter.cpp:236
CCrypter()
Definition: crypter.h:88
boost::signals2::signal< void(CCryptoKeyStore *wallet)> NotifyStatusChanged
Definition: crypter.h:190
void GetKeys(std::set< CKeyID > &setAddress) const
Definition: crypter.h:171
#define LOCK(cs)
Definition: sync.h:157
bool fKeySet
Definition: crypter.h:73
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: allocators.h:254
An encapsulated public key.
Definition: key.h:43
bool Unlock(const CKeyingMaterial &vMasterKeyIn)
Definition: crypter.cpp:149
bool Decrypt(const std::vector< unsigned char > &vchCiphertext, CKeyingMaterial &vchPlaintext)
Definition: crypter.cpp:76
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)
Definition: crypter.cpp:178
unsigned char chKey[WALLET_CRYPTO_KEY_SIZE]
Definition: crypter.h:71
static LockedPageManager & Instance()
Definition: allocators.h:140
256-bit unsigned integer
Definition: uint256.h:532
const unsigned int WALLET_CRYPTO_SALT_SIZE
Definition: crypter.h:16
CryptedKeyMap mapCryptedKeys
Definition: crypter.h:117
void UnlockRange(void *p, size_t size)
Definition: allocators.h:70
A reference to a CKey: the Hash160 of its serialized public key.
Definition: key.h:27
~CCrypter()
Definition: crypter.h:99
std::vector< unsigned char > vchSalt
Definition: crypter.h:38
bool fUseCrypto
Definition: crypter.h:123
bool EncryptSecret(const CKeyingMaterial &vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256 &nIV, std::vector< unsigned char > &vchCiphertext)
Definition: crypter.cpp:104
An encapsulated private key.
Definition: key.h:180
unsigned int nDeriveIterations
Definition: crypter.h:42
Basic key store, that keeps keys in an address->secret map.
Definition: keystore.h:63