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
No known key found for this signature in database
GPG key ID: F4ACA0183641E010
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();

View file

@ -57,15 +57,16 @@ namespace cryptonote
account_keys& operator=(account_keys const&) = default;
void encrypt_wrapper(const crypto::chacha_key &key, const bool all_keys);
void decrypt_wrapper(const crypto::chacha_key &key, const bool all_keys);
void decrypt_legacy(const crypto::chacha_key &key);
void encrypt(const crypto::chacha_key &key);
void decrypt(const crypto::chacha_key &key);
void encrypt_viewkey(const crypto::chacha_key &key);
void decrypt_viewkey(const crypto::chacha_key &key);
hw::device& get_device() const ;
void set_device( hw::device &hwdev) ;
private:
void chacha_wrapper(const crypto::chacha_key &key, const bool all_keys);
void xor_with_key_stream(const crypto::chacha_key &key);
};
/************************************************************************/
@ -99,12 +100,10 @@ namespace cryptonote
void forget_spend_key();
const std::vector<crypto::secret_key> &get_multisig_keys() const { return m_keys.m_multisig_keys; }
void encrypt_keys(const crypto::chacha_key &key) { m_keys.encrypt_wrapper(key, true); }
void encrypt_keys_same_iv(const crypto::chacha_key &key) { m_keys.decrypt_wrapper(key, true); } // encryption with the same IV is the same as decryption due to symmetry
void decrypt_keys(const crypto::chacha_key &key) { m_keys.decrypt_wrapper(key, true); }
void encrypt_viewkey(const crypto::chacha_key &key) { m_keys.encrypt_wrapper(key, false); }
void decrypt_viewkey(const crypto::chacha_key &key) { m_keys.decrypt_wrapper(key, false); }
void decrypt_legacy(const crypto::chacha_key &key) { m_keys.decrypt_legacy(key); }
void encrypt_keys(const crypto::chacha_key &key) { m_keys.encrypt(key); }
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); }
template <class t_archive>
inline void serialize(t_archive &a, const unsigned int /*ver*/)