diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp index 3ba5638bfa9..2424ca98a89 100644 --- a/src/cryptonote_basic/account.cpp +++ b/src/cryptonote_basic/account.cpp @@ -84,15 +84,18 @@ DISABLE_VS_WARNINGS(4244 4345) return buffer1; } //----------------------------------------------------------------- - void account_keys::xor_with_key_stream(const crypto::chacha_key &key) + void account_keys::xor_with_key_stream(const crypto::chacha_key &key, bool skip_viewkey) { // encrypt a large enough byte stream with chacha20 epee::wipeable_string key_stream = get_key_stream(key, m_encryption_iv, sizeof(crypto::secret_key) * (2 + m_multisig_keys.size())); const char *ptr = key_stream.data(); for (size_t i = 0; i < sizeof(crypto::secret_key); ++i) m_spend_secret_key.data[i] ^= *ptr++; - for (size_t i = 0; i < sizeof(crypto::secret_key); ++i) - m_view_secret_key.data[i] ^= *ptr++; + if (skip_viewkey) + ptr += sizeof(crypto::secret_key); + else + for (size_t i = 0; i < sizeof(crypto::secret_key); ++i) + m_view_secret_key.data[i] ^= *ptr++; for (crypto::secret_key &k: m_multisig_keys) { for (size_t i = 0; i < sizeof(crypto::secret_key); ++i) @@ -126,6 +129,17 @@ DISABLE_VS_WARNINGS(4244 4345) encrypt_viewkey(key); } //----------------------------------------------------------------- + void account_keys::encrypt_except_viewkey(const crypto::chacha_key &key) + { + m_encryption_iv = crypto::rand(); + xor_with_key_stream(key, /*skip_viewkey=*/true); + } + //----------------------------------------------------------------- + void account_keys::decrypt_except_viewkey(const crypto::chacha_key &key) + { + xor_with_key_stream(key, /*skip_viewkey=*/true); + } + //----------------------------------------------------------------- account_base::account_base() { set_null(); diff --git a/src/cryptonote_basic/account.h b/src/cryptonote_basic/account.h index de591203299..05128c37ad5 100644 --- a/src/cryptonote_basic/account.h +++ b/src/cryptonote_basic/account.h @@ -59,12 +59,14 @@ namespace cryptonote void decrypt(const crypto::chacha_key &key); void encrypt_viewkey(const crypto::chacha_key &key); void decrypt_viewkey(const crypto::chacha_key &key); + void encrypt_except_viewkey(const crypto::chacha_key &key); + void decrypt_except_viewkey(const crypto::chacha_key &key); hw::device& get_device() const ; void set_device( hw::device &hwdev) ; private: - void xor_with_key_stream(const crypto::chacha_key &key); + void xor_with_key_stream(const crypto::chacha_key &key, bool skip_viewkey = false); }; /************************************************************************/ @@ -102,6 +104,8 @@ namespace cryptonote void decrypt_keys(const crypto::chacha_key &key) { m_keys.decrypt(key); } void encrypt_viewkey(const crypto::chacha_key &key) { m_keys.encrypt_viewkey(key); } void decrypt_viewkey(const crypto::chacha_key &key) { m_keys.decrypt_viewkey(key); } + void encrypt_keys_except_viewkey(const crypto::chacha_key &key) { m_keys.encrypt_except_viewkey(key); } + void decrypt_keys_except_viewkey(const crypto::chacha_key &key) { m_keys.decrypt_except_viewkey(key); } template inline void serialize(t_archive &a, const unsigned int /*ver*/) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index c22673947e0..2609a887c3d 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4917,8 +4917,8 @@ boost::optional wallet2::get_keys_file_data(const crypt if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only) { - account.encrypt_viewkey(key); - account.decrypt_keys(key); + // since view key is already decrypted, we exclude it. + account.decrypt_keys_except_viewkey(key); } if (watch_only || background_keys_file) @@ -5147,8 +5147,8 @@ void wallet2::setup_keys(const epee::wipeable_string &password) // re-encrypt, but keep viewkey unencrypted if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only) { - m_account.encrypt_keys(key); - m_account.decrypt_viewkey(key); + // we don't encrypt the view key since its used for scanning. + m_account.encrypt_keys_except_viewkey(key); } m_cache_key = derive_cache_key(key, config::HASH_KEY_WALLET_CACHE); @@ -5789,16 +5789,14 @@ bool wallet2::is_key_encryption_enabled() const void wallet2::encrypt_keys(const crypto::chacha_key &key) { - m_account.encrypt_keys(key); - m_account.decrypt_viewkey(key); + m_account.encrypt_keys_except_viewkey(key); } void wallet2::decrypt_keys(const crypto::chacha_key &key) { verify_password_with_cached_key(key); - m_account.encrypt_viewkey(key); - m_account.decrypt_keys(key); + m_account.decrypt_keys_except_viewkey(key); } void wallet2::encrypt_keys(const epee::wipeable_string &password)