Revert "Use domain-separated ChaCha20 for in-memory key encryption"

This reverts commit 921dd8dde5.
This commit is contained in:
luigi1111
2020-08-17 14:08:59 -05:00
parent 43a4fd9e16
commit 765db1ae7a
6 changed files with 50 additions and 172 deletions

View File

@@ -61,8 +61,7 @@ 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");
@@ -71,38 +70,25 @@ DISABLE_VS_WARNINGS(4244 4345)
data[sizeof(base_key)] = config::HASH_KEY_MEMORY;
crypto::generate_chacha_key(data.data(), sizeof(data), key, 1);
}
// Prepare IVs and start chacha for encryption
void account_keys::encrypt_wrapper(const crypto::chacha_key &key, const bool all_keys)
//-----------------------------------------------------------------
static epee::wipeable_string get_key_stream(const crypto::chacha_key &base_key, const crypto::chacha_iv &iv, size_t bytes)
{
// Set a fresh IV only for all-key encryption
if (all_keys)
m_encryption_iv = crypto::rand<crypto::chacha_iv>();
// derive a new key
crypto::chacha_key key;
derive_key(base_key, key);
// Now do the chacha
chacha_wrapper(key, all_keys);
// 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;
}
// Start chacha for decryption
void account_keys::decrypt_wrapper(const crypto::chacha_key &key, const bool all_keys)
//-----------------------------------------------------------------
void account_keys::xor_with_key_stream(const crypto::chacha_key &key)
{
chacha_wrapper(key, all_keys);
}
// Decrypt keys using the legacy method
void account_keys::decrypt_legacy(const crypto::chacha_key &key)
{
// 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();
// 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)
@@ -113,39 +99,33 @@ DISABLE_VS_WARNINGS(4244 4345)
k.data[i] ^= *ptr++;
}
}
// Perform chacha on either the view key or all keys
void account_keys::chacha_wrapper(const crypto::chacha_key &key, const bool all_keys)
//-----------------------------------------------------------------
void account_keys::encrypt(const crypto::chacha_key &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));
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);
}
//-----------------------------------------------------------------
account_base::account_base()
{
set_null();