Do memwipe for critical secret keys copied to rct::key

This commit is contained in:
stoffu 2018-08-16 22:08:58 +09:00
parent b780cf4db1
commit 1f2409e9e2
No known key found for this signature in database
GPG key ID: 41DAB8343A9EC012
4 changed files with 15 additions and 3 deletions

View file

@ -516,6 +516,7 @@ namespace cryptonote
uint64_t amount_in = 0, amount_out = 0; uint64_t amount_in = 0, amount_out = 0;
rct::ctkeyV inSk; rct::ctkeyV inSk;
inSk.reserve(sources.size());
// mixRing indexing is done the other way round for simple // mixRing indexing is done the other way round for simple
rct::ctkeyM mixRing(use_simple_rct ? sources.size() : n_total_outs); rct::ctkeyM mixRing(use_simple_rct ? sources.size() : n_total_outs);
rct::keyV destinations; rct::keyV destinations;
@ -532,6 +533,7 @@ namespace cryptonote
ctkey.dest = rct::sk2rct(in_contexts[i].in_ephemeral.sec); ctkey.dest = rct::sk2rct(in_contexts[i].in_ephemeral.sec);
ctkey.mask = sources[i].mask; ctkey.mask = sources[i].mask;
inSk.push_back(ctkey); inSk.push_back(ctkey);
memwipe(&ctkey, sizeof(rct::ctkey));
// inPk: (public key, commitment) // inPk: (public key, commitment)
// will be done when filling in mixRing // will be done when filling in mixRing
if (msout) if (msout)
@ -590,6 +592,7 @@ namespace cryptonote
tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, msout ? &kLRki : NULL, msout, index, outSk, bulletproof, hwdev); tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, msout ? &kLRki : NULL, msout, index, outSk, bulletproof, hwdev);
else else
tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, msout ? &kLRki[0] : NULL, msout, sources[0].real_output, outSk, bulletproof, hwdev); // same index assumption tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, msout ? &kLRki[0] : NULL, msout, sources[0].real_output, outSk, bulletproof, hwdev); // same index assumption
memwipe(inSk.data(), inSk.size() * sizeof(rct::ctkey));
CHECK_AND_ASSERT_MES(tx.vout.size() == outSk.size(), false, "outSk size does not match vout"); CHECK_AND_ASSERT_MES(tx.vout.size() == outSk.size(), false, "outSk size does not match vout");

View file

@ -47,9 +47,12 @@ namespace cryptonote
crypto::secret_key get_multisig_blinded_secret_key(const crypto::secret_key &key) crypto::secret_key get_multisig_blinded_secret_key(const crypto::secret_key &key)
{ {
rct::keyV data; rct::keyV data;
data.reserve(2);
data.push_back(rct::sk2rct(key)); data.push_back(rct::sk2rct(key));
data.push_back(multisig_salt); data.push_back(multisig_salt);
return rct::rct2sk(rct::hash_to_scalar(data)); crypto::secret_key result = rct::rct2sk(rct::hash_to_scalar(data));
memwipe(&data[0], sizeof(rct::key));
return result;
} }
//----------------------------------------------------------------- //-----------------------------------------------------------------
void generate_multisig_N_N(const account_keys &keys, const std::vector<crypto::public_key> &spend_keys, std::vector<crypto::secret_key> &multisig_keys, rct::key &spend_skey, rct::key &spend_pkey) void generate_multisig_N_N(const account_keys &keys, const std::vector<crypto::public_key> &spend_keys, std::vector<crypto::secret_key> &multisig_keys, rct::key &spend_skey, rct::key &spend_pkey)

View file

@ -492,7 +492,9 @@ namespace rct {
for (size_t j = 0; j < outPk.size(); j++) { for (size_t j = 0; j < outPk.size(); j++) {
sc_sub(sk[rows].bytes, sk[rows].bytes, outSk[j].mask.bytes); //subtract output masks in last row.. sc_sub(sk[rows].bytes, sk[rows].bytes, outSk[j].mask.bytes); //subtract output masks in last row..
} }
return MLSAG_Gen(message, M, sk, kLRki, mscout, index, rows, hwdev); mgSig result = MLSAG_Gen(message, M, sk, kLRki, mscout, index, rows, hwdev);
memwipe(sk.data(), sk.size() * sizeof(key));
return result;
} }
@ -521,7 +523,9 @@ namespace rct {
M[i][0] = pubs[i].dest; M[i][0] = pubs[i].dest;
subKeys(M[i][1], pubs[i].mask, Cout); subKeys(M[i][1], pubs[i].mask, Cout);
} }
return MLSAG_Gen(message, M, sk, kLRki, mscout, index, rows, hwdev); mgSig result = MLSAG_Gen(message, M, sk, kLRki, mscout, index, rows, hwdev);
memwipe(&sk[0], sizeof(key));
return result;
} }

View file

@ -3217,6 +3217,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
for (const auto &msk: multisig_keys) for (const auto &msk: multisig_keys)
sc_add(skey.bytes, skey.bytes, rct::sk2rct(msk).bytes); sc_add(skey.bytes, skey.bytes, rct::sk2rct(msk).bytes);
THROW_WALLET_EXCEPTION_IF(!(rct::rct2sk(skey) == spend_secret_key), error::invalid_multisig_seed); THROW_WALLET_EXCEPTION_IF(!(rct::rct2sk(skey) == spend_secret_key), error::invalid_multisig_seed);
memwipe(&skey, sizeof(rct::key));
m_account.make_multisig(view_secret_key, spend_secret_key, spend_public_key, multisig_keys); m_account.make_multisig(view_secret_key, spend_secret_key, spend_public_key, multisig_keys);
m_account.finalize_multisig(spend_public_key); m_account.finalize_multisig(spend_public_key);
@ -3563,6 +3564,7 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
MINFO("Creating multisig address..."); MINFO("Creating multisig address...");
CHECK_AND_ASSERT_THROW_MES(m_account.make_multisig(view_skey, rct::rct2sk(spend_skey), rct::rct2pk(spend_pkey), multisig_keys), CHECK_AND_ASSERT_THROW_MES(m_account.make_multisig(view_skey, rct::rct2sk(spend_skey), rct::rct2pk(spend_pkey), multisig_keys),
"Failed to create multisig wallet due to bad keys"); "Failed to create multisig wallet due to bad keys");
memwipe(&spend_skey, sizeof(rct::key));
m_account_public_address = m_account.get_keys().m_account_address; m_account_public_address = m_account.get_keys().m_account_address;
m_watch_only = false; m_watch_only = false;