@@ -576,6 +576,35 @@ void CWallet::UpgradeDescriptorCache()
576576 SetWalletFlag (WALLET_FLAG_LAST_HARDENED_XPUB_CACHED);
577577}
578578
579+ /* Given a wallet passphrase string and an unencrypted master key, determine the proper key
580+ * derivation parameters (should take at least 100ms) and encrypt the master key. */
581+ static bool EncryptMasterKey (const SecureString& wallet_passphrase, const CKeyingMaterial& plain_master_key, CMasterKey& master_key)
582+ {
583+ constexpr MillisecondsDouble target{100 };
584+ auto start{SteadyClock::now ()};
585+ CCrypter crypter;
586+
587+ crypter.SetKeyFromPassphrase (wallet_passphrase, master_key.vchSalt , master_key.nDeriveIterations , master_key.nDerivationMethod );
588+ master_key.nDeriveIterations = static_cast <unsigned int >(master_key.nDeriveIterations * target / (SteadyClock::now () - start));
589+
590+ start = SteadyClock::now ();
591+ crypter.SetKeyFromPassphrase (wallet_passphrase, master_key.vchSalt , master_key.nDeriveIterations , master_key.nDerivationMethod );
592+ master_key.nDeriveIterations = (master_key.nDeriveIterations + static_cast <unsigned int >(master_key.nDeriveIterations * target / (SteadyClock::now () - start))) / 2 ;
593+
594+ if (master_key.nDeriveIterations < CMasterKey::DEFAULT_DERIVE_ITERATIONS) {
595+ master_key.nDeriveIterations = CMasterKey::DEFAULT_DERIVE_ITERATIONS;
596+ }
597+
598+ if (!crypter.SetKeyFromPassphrase (wallet_passphrase, master_key.vchSalt , master_key.nDeriveIterations , master_key.nDerivationMethod )) {
599+ return false ;
600+ }
601+ if (!crypter.Encrypt (plain_master_key, master_key.vchCryptedKey )) {
602+ return false ;
603+ }
604+
605+ return true ;
606+ }
607+
579608bool CWallet::Unlock (const SecureString& strWalletPassphrase)
580609{
581610 CCrypter crypter;
@@ -619,24 +648,11 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
619648 return false ;
620649 if (Unlock (_vMasterKey))
621650 {
622- constexpr MillisecondsDouble target{100 };
623- auto start{SteadyClock::now ()};
624- crypter.SetKeyFromPassphrase (strNewWalletPassphrase, pMasterKey.second .vchSalt , pMasterKey.second .nDeriveIterations , pMasterKey.second .nDerivationMethod );
625- pMasterKey.second .nDeriveIterations = static_cast <unsigned int >(pMasterKey.second .nDeriveIterations * target / (SteadyClock::now () - start));
626-
627- start = SteadyClock::now ();
628- crypter.SetKeyFromPassphrase (strNewWalletPassphrase, pMasterKey.second .vchSalt , pMasterKey.second .nDeriveIterations , pMasterKey.second .nDerivationMethod );
629- pMasterKey.second .nDeriveIterations = (pMasterKey.second .nDeriveIterations + static_cast <unsigned int >(pMasterKey.second .nDeriveIterations * target / (SteadyClock::now () - start))) / 2 ;
630-
631- if (pMasterKey.second .nDeriveIterations < CMasterKey::DEFAULT_DERIVE_ITERATIONS)
632- pMasterKey.second .nDeriveIterations = CMasterKey::DEFAULT_DERIVE_ITERATIONS;
633-
651+ if (!EncryptMasterKey (strNewWalletPassphrase, _vMasterKey, pMasterKey.second )) {
652+ return false ;
653+ }
634654 WalletLogPrintf (" Wallet passphrase changed to an nDeriveIterations of %i\n " , pMasterKey.second .nDeriveIterations );
635655
636- if (!crypter.SetKeyFromPassphrase (strNewWalletPassphrase, pMasterKey.second .vchSalt , pMasterKey.second .nDeriveIterations , pMasterKey.second .nDerivationMethod ))
637- return false ;
638- if (!crypter.Encrypt (_vMasterKey, pMasterKey.second .vchCryptedKey ))
639- return false ;
640656 WalletBatch (GetDatabase ()).WriteMasterKey (pMasterKey.first , pMasterKey.second );
641657 if (fWasLocked )
642658 Lock ();
@@ -822,25 +838,10 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
822838 kMasterKey .vchSalt .resize (WALLET_CRYPTO_SALT_SIZE);
823839 GetStrongRandBytes (kMasterKey .vchSalt );
824840
825- CCrypter crypter;
826- constexpr MillisecondsDouble target{100 };
827- auto start{SteadyClock::now ()};
828- crypter.SetKeyFromPassphrase (strWalletPassphrase, kMasterKey .vchSalt , CMasterKey::DEFAULT_DERIVE_ITERATIONS, kMasterKey .nDerivationMethod );
829- kMasterKey .nDeriveIterations = static_cast <unsigned int >(CMasterKey::DEFAULT_DERIVE_ITERATIONS * target / (SteadyClock::now () - start));
830-
831- start = SteadyClock::now ();
832- crypter.SetKeyFromPassphrase (strWalletPassphrase, kMasterKey .vchSalt , kMasterKey .nDeriveIterations , kMasterKey .nDerivationMethod );
833- kMasterKey .nDeriveIterations = (kMasterKey .nDeriveIterations + static_cast <unsigned int >(kMasterKey .nDeriveIterations * target / (SteadyClock::now () - start))) / 2 ;
834-
835- if (kMasterKey .nDeriveIterations < CMasterKey::DEFAULT_DERIVE_ITERATIONS)
836- kMasterKey .nDeriveIterations = CMasterKey::DEFAULT_DERIVE_ITERATIONS;
837-
838- WalletLogPrintf (" Encrypting Wallet with an nDeriveIterations of %i\n " , kMasterKey .nDeriveIterations );
839-
840- if (!crypter.SetKeyFromPassphrase (strWalletPassphrase, kMasterKey .vchSalt , kMasterKey .nDeriveIterations , kMasterKey .nDerivationMethod ))
841- return false ;
842- if (!crypter.Encrypt (_vMasterKey, kMasterKey .vchCryptedKey ))
841+ if (!EncryptMasterKey (strWalletPassphrase, _vMasterKey, kMasterKey )) {
843842 return false ;
843+ }
844+ WalletLogPrintf (" Encrypting Wallet with an nDeriveIterations of %i\n " , kMasterKey .nDeriveIterations );
844845
845846 {
846847 LOCK2 (m_relock_mutex, cs_wallet);
0 commit comments