| 269 | } |
| 270 | |
| 271 | bool CWallet::EncryptWallet(const SecureString &strWalletPassphrase) { |
| 272 | if (IsEncrypted()) |
| 273 | return false; |
| 274 | |
| 275 | CKeyingMaterial vMasterKey; |
| 276 | RandAddSeedPerfmon(); |
| 277 | |
| 278 | vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); |
| 279 | GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); |
| 280 | |
| 281 | CMasterKey kMasterKey; |
| 282 | RandAddSeedPerfmon(); |
| 283 | |
| 284 | kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); |
| 285 | GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); |
| 286 | |
| 287 | CCrypter crypter; |
| 288 | int64_t nStartTime = GetTimeMillis(); |
| 289 | crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod); |
| 290 | kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime)); |
| 291 | |
| 292 | nStartTime = GetTimeMillis(); |
| 293 | crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, |
| 294 | kMasterKey.nDerivationMethod); |
| 295 | kMasterKey.nDeriveIterations = |
| 296 | (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / |
| 297 | 2; |
| 298 | |
| 299 | if (kMasterKey.nDeriveIterations < 25000) kMasterKey.nDeriveIterations = 25000; |
| 300 | |
| 301 | LogPrint(BCLog::INFO, "Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations); |
| 302 | |
| 303 | if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, |
| 304 | kMasterKey.nDerivationMethod)) |
| 305 | return false; |
| 306 | if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey)) |
| 307 | return false; |
| 308 | |
| 309 | { |
| 310 | LOCK(cs_wallet); |
| 311 | mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; |
| 312 | if (fFileBacked) { |
| 313 | assert(!pWalletDbEncryption); |
| 314 | pWalletDbEncryption = new CWalletDB(strWalletFile); |
| 315 | if (!pWalletDbEncryption->TxnBegin()) { |
| 316 | delete pWalletDbEncryption; |
| 317 | pWalletDbEncryption = nullptr; |
| 318 | return false; |
| 319 | } |
| 320 | pWalletDbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); |
| 321 | } |
| 322 | |
| 323 | if (!EncryptKeys(vMasterKey)) { |
| 324 | if (fFileBacked) { |
| 325 | pWalletDbEncryption->TxnAbort(); |
| 326 | delete pWalletDbEncryption; |
| 327 | } |
| 328 | // We now probably have half of our keys encrypted in memory, and half not... |
no test coverage detected