aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_basic/account.cpp
diff options
context:
space:
mode:
authorAlexander Blair <snipa@jagtech.io>2020-08-16 12:39:58 -0700
committerAlexander Blair <snipa@jagtech.io>2020-08-16 12:39:59 -0700
commit6d29ee6c525dd1aa677e6a2a610f3aeb74fd23b2 (patch)
tree90237ee6130b0bcf2c22d3aba121bd944a062df5 /src/cryptonote_basic/account.cpp
parentMerge pull request #6337 (diff)
parentUse domain-separated ChaCha20 for in-memory key encryption (diff)
downloadmonero-6d29ee6c525dd1aa677e6a2a610f3aeb74fd23b2.tar.xz
Merge pull request #6493
921dd8dde Use domain-separated ChaCha20 for in-memory key encryption (Sarang Noether)
Diffstat (limited to 'src/cryptonote_basic/account.cpp')
-rw-r--r--src/cryptonote_basic/account.cpp102
1 files changed, 61 insertions, 41 deletions
diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp
index 36ff41684..b366985ab 100644
--- a/src/cryptonote_basic/account.cpp
+++ b/src/cryptonote_basic/account.cpp
@@ -61,7 +61,8 @@ DISABLE_VS_WARNINGS(4244 4345)
m_device = &hwdev;
MCDEBUG("device", "account_keys::set_device device type: "<<typeid(hwdev).name());
}
- //-----------------------------------------------------------------
+
+ // Generate a derived chacha key
static void derive_key(const crypto::chacha_key &base_key, crypto::chacha_key &key)
{
static_assert(sizeof(base_key) == sizeof(crypto::hash), "chacha key and hash should be the same size");
@@ -70,25 +71,38 @@ DISABLE_VS_WARNINGS(4244 4345)
data[sizeof(base_key)] = config::HASH_KEY_MEMORY;
crypto::generate_chacha_key(data.data(), sizeof(data), key, 1);
}
- //-----------------------------------------------------------------
- static epee::wipeable_string get_key_stream(const crypto::chacha_key &base_key, const crypto::chacha_iv &iv, size_t bytes)
+
+ // Prepare IVs and start chacha for encryption
+ void account_keys::encrypt_wrapper(const crypto::chacha_key &key, const bool all_keys)
{
- // derive a new key
- crypto::chacha_key key;
- derive_key(base_key, key);
+ // Set a fresh IV only for all-key encryption
+ if (all_keys)
+ m_encryption_iv = crypto::rand<crypto::chacha_iv>();
- // chacha
- epee::wipeable_string buffer0(std::string(bytes, '\0'));
- epee::wipeable_string buffer1 = buffer0;
- crypto::chacha20(buffer0.data(), buffer0.size(), key, iv, buffer1.data());
- return buffer1;
+ // Now do the chacha
+ chacha_wrapper(key, all_keys);
}
- //-----------------------------------------------------------------
- void account_keys::xor_with_key_stream(const crypto::chacha_key &key)
+
+ // Start chacha for decryption
+ void account_keys::decrypt_wrapper(const crypto::chacha_key &key, const bool all_keys)
+ {
+ chacha_wrapper(key, all_keys);
+ }
+
+ // Decrypt keys using the legacy method
+ void account_keys::decrypt_legacy(const crypto::chacha_key &key)
{
- // 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();
+ // Derive domain-separated chacha key
+ crypto::chacha_key derived_key;
+ derive_key(key, derived_key);
+
+ // Build key stream
+ epee::wipeable_string temp(std::string(sizeof(crypto::secret_key)*(2 + m_multisig_keys.size()), '\0'));
+ epee::wipeable_string stream = temp;
+ crypto::chacha20(temp.data(), temp.size(), derived_key, m_encryption_iv, stream.data());
+
+ // Decrypt all keys
+ const char *ptr = 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)
@@ -99,33 +113,39 @@ DISABLE_VS_WARNINGS(4244 4345)
k.data[i] ^= *ptr++;
}
}
- //-----------------------------------------------------------------
- void account_keys::encrypt(const crypto::chacha_key &key)
+
+ // Perform chacha on either the view key or all keys
+ void account_keys::chacha_wrapper(const crypto::chacha_key &key, const bool all_keys)
{
- m_encryption_iv = crypto::rand<crypto::chacha_iv>();
- xor_with_key_stream(key);
- }
- //-----------------------------------------------------------------
- void account_keys::decrypt(const crypto::chacha_key &key)
- {
- xor_with_key_stream(key);
- }
- //-----------------------------------------------------------------
- void account_keys::encrypt_viewkey(const crypto::chacha_key &key)
- {
- // 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);
- const char *ptr = key_stream.data();
- ptr += sizeof(crypto::secret_key);
- for (size_t i = 0; i < sizeof(crypto::secret_key); ++i)
- m_view_secret_key.data[i] ^= *ptr++;
- }
- //-----------------------------------------------------------------
- void account_keys::decrypt_viewkey(const crypto::chacha_key &key)
- {
- encrypt_viewkey(key);
+ // Derive domain-seprated chacha key
+ crypto::chacha_key derived_key;
+ derive_key(key, derived_key);
+
+ // Chacha the specified keys using the appropriate IVs
+ if (all_keys)
+ {
+ // Spend key
+ crypto::secret_key temp_key;
+ chacha20((char *) &m_spend_secret_key, sizeof(crypto::secret_key), derived_key, m_encryption_iv, (char *) &temp_key);
+ memcpy(&m_spend_secret_key, &temp_key, sizeof(crypto::secret_key));
+ memwipe(&temp_key, sizeof(crypto::secret_key));
+
+ // Multisig keys
+ std::vector<crypto::secret_key> temp_keys;
+ temp_keys.reserve(m_multisig_keys.size());
+ temp_keys.resize(m_multisig_keys.size());
+ chacha20((char *) &m_multisig_keys[0], sizeof(crypto::secret_key)*m_multisig_keys.size(), derived_key, m_encryption_iv, (char *) &temp_keys[0]);
+ memcpy(&m_multisig_keys[0], &temp_keys[0], sizeof(crypto::secret_key)*temp_keys.size());
+ memwipe(&temp_keys[0], sizeof(crypto::secret_key)*temp_keys.size());
+ }
+
+ // View key
+ crypto::secret_key temp_key;
+ chacha20((char *) &m_view_secret_key, sizeof(crypto::secret_key), derived_key, m_encryption_iv, (char *) &temp_key);
+ memcpy(&m_view_secret_key, &temp_key, sizeof(crypto::secret_key));
+ memwipe(&temp_key, sizeof(crypto::secret_key));
}
- //-----------------------------------------------------------------
+
account_base::account_base()
{
set_null();