Securely erase memory & reduce public API

This commit is contained in:
Nik Bougalis
2017-09-06 10:13:40 -07:00
parent dd52bdd2c4
commit 39f9135104
4 changed files with 55 additions and 61 deletions

View File

@@ -19,6 +19,7 @@
#include <BeastConfig.h> #include <BeastConfig.h>
#include <ripple/basics/contract.h> #include <ripple/basics/contract.h>
#include <ripple/beast/crypto/secure_erase.h>
#include <ripple/crypto/GenerateDeterministicKey.h> #include <ripple/crypto/GenerateDeterministicKey.h>
#include <ripple/crypto/impl/ec_key.h> #include <ripple/crypto/impl/ec_key.h>
#include <ripple/crypto/impl/openssl.h> #include <ripple/crypto/impl/openssl.h>
@@ -74,8 +75,6 @@ copy_uint32 (FwdIt out, std::uint32_t v)
*out = v & 0xff; *out = v & 0xff;
} }
// #define EC_DEBUG
// Functions to add support for deterministic EC keys // Functions to add support for deterministic EC keys
// --> seed // --> seed
@@ -94,12 +93,12 @@ static bignum generateRootDeterministicKey (uint128 const& seed)
std::copy(seed.begin(), seed.end(), buf.begin()); std::copy(seed.begin(), seed.end(), buf.begin());
copy_uint32 (buf.begin() + 16, seq++); copy_uint32 (buf.begin() + 16, seq++);
auto root = sha512Half(buf); auto root = sha512Half(buf);
std::fill (buf.begin(), buf.end(), 0); // security erase beast::secure_erase(buf.data(), buf.size());
privKey.assign (root.data(), root.size()); privKey.assign (root.data(), root.size());
root.zero(); // security erase beast::secure_erase(root.data(), root.size());
} }
while (privKey.is_zero() || privKey >= secp256k1curve.order); while (privKey.is_zero() || privKey >= secp256k1curve.order);
beast::secure_erase(&seq, sizeof(seq));
return privKey; return privKey;
} }
@@ -153,8 +152,9 @@ static bignum makeHash (Blob const& pubGen, int seq, bignum const& order)
copy_uint32 (buf.begin() + 33, seq); copy_uint32 (buf.begin() + 33, seq);
copy_uint32 (buf.begin() + 37, subSeq++); copy_uint32 (buf.begin() + 37, subSeq++);
auto root = sha512Half_s(buf); auto root = sha512Half_s(buf);
std::fill(buf.begin(), buf.end(), 0); // security erase beast::secure_erase(buf.data(), buf.size());
result.assign (root.data(), root.size()); result.assign (root.data(), root.size());
beast::secure_erase(root.data(), root.size());
} }
while (result.is_zero() || result >= order); while (result.is_zero() || result >= order);

View File

@@ -88,30 +88,6 @@ operator!= (SecretKey const& lhs,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Produces a sequence of secp256k1 key pairs. */
class Generator
{
private:
Blob gen_; // VFALCO compile time size?
public:
explicit
Generator (Seed const& seed);
/** Generate the nth key pair.
The seed is required to produce the private key.
*/
std::pair<PublicKey, SecretKey>
operator()(Seed const& seed, std::size_t ordinal) const;
/** Generate the nth public key. */
PublicKey
operator()(std::size_t ordinal) const;
};
//------------------------------------------------------------------------------
/** Parse a secret key */ /** Parse a secret key */
template <> template <>
boost::optional<SecretKey> boost::optional<SecretKey>

View File

@@ -25,6 +25,7 @@
#include <ripple/basics/contract.h> #include <ripple/basics/contract.h>
#include <ripple/basics/Buffer.h> #include <ripple/basics/Buffer.h>
#include <ripple/basics/Slice.h> #include <ripple/basics/Slice.h>
#include <ripple/beast/crypto/secure_erase.h>
#include <cassert> #include <cassert>
#include <cstdint> #include <cstdint>
#include <iomanip> #include <iomanip>
@@ -198,8 +199,8 @@ public:
} }
void secureErase () void secureErase ()
{ {
memset (& (mData.front ()), 0, mData.size ()); beast::secure_erase(mData.data(), mData.size());
erase (); mData.clear ();
} }
void erase () void erase ()
{ {

View File

@@ -56,35 +56,46 @@ SecretKey::to_string() const
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Produces a sequence of secp256k1 key pairs. */
Generator::Generator (Seed const& seed) class Generator
{ {
uint128 ui; private:
std::memcpy(ui.data(), Blob gen_; // VFALCO compile time size?
seed.data(), seed.size());
gen_ = generateRootDeterministicPublicKey(ui);
}
std::pair<PublicKey, SecretKey> public:
Generator::operator()(Seed const& seed, std::size_t ordinal) const explicit
{ Generator (Seed const& seed)
uint128 ui; {
std::memcpy(ui.data(), seed.data(), seed.size()); // FIXME: Avoid copying the seed into a uint128 key only to have
auto gsk = generatePrivateDeterministicKey(gen_, ui, ordinal); // generateRootDeterministicPublicKey copy out of it.
auto gpk = generatePublicDeterministicKey(gen_, ordinal); uint128 ui;
SecretKey const sk(Slice{ gsk.data(), gsk.size() }); std::memcpy(ui.data(),
PublicKey const pk(Slice{ gpk.data(), gpk.size() }); seed.data(), seed.size());
beast::secure_erase(ui.data(), ui.size()); gen_ = generateRootDeterministicPublicKey(ui);
beast::secure_erase(gsk.data(), gsk.size()); }
return { pk, sk };
}
PublicKey /** Generate the nth key pair.
Generator::operator()(std::size_t ordinal) const
{ The seed is required to produce the private key.
auto gpk = generatePublicDeterministicKey(gen_, ordinal); */
return PublicKey(Slice{ gpk.data(), gpk.size() }); std::pair<PublicKey, SecretKey>
} operator()(Seed const& seed, std::size_t ordinal) const
{
// FIXME: Avoid copying the seed into a uint128 key only to have
// generatePrivateDeterministicKey copy out of it.
uint128 ui;
std::memcpy(ui.data(), seed.data(), seed.size());
auto gsk = generatePrivateDeterministicKey(gen_, ui, ordinal);
auto gpk = generatePublicDeterministicKey(gen_, ordinal);
SecretKey const sk(Slice
{ gsk.data(), gsk.size() });
PublicKey const pk(Slice
{ gpk.data(), gpk.size() });
beast::secure_erase(ui.data(), ui.size());
beast::secure_erase(gsk.data(), gsk.size());
return {pk, sk};
}
};
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -192,19 +203,25 @@ generateSecretKey (KeyType type, Seed const& seed)
{ {
if (type == KeyType::ed25519) if (type == KeyType::ed25519)
{ {
auto const key = sha512Half_s(Slice( auto key = sha512Half_s(Slice(
seed.data(), seed.size())); seed.data(), seed.size()));
return SecretKey(Slice{ key.data(), key.size() }); SecretKey sk = Slice{ key.data(), key.size() };
beast::secure_erase(key.data(), key.size());
return sk;
} }
if (type == KeyType::secp256k1) if (type == KeyType::secp256k1)
{ {
// FIXME: Avoid copying the seed into a uint128 key only to have
// generateRootDeterministicPrivateKey copy out of it.
uint128 ps; uint128 ps;
std::memcpy(ps.data(), std::memcpy(ps.data(),
seed.data(), seed.size()); seed.data(), seed.size());
auto const upk = auto const upk =
generateRootDeterministicPrivateKey(ps); generateRootDeterministicPrivateKey(ps);
return SecretKey(Slice{ upk.data(), upk.size() }); SecretKey sk = Slice{ upk.data(), upk.size() };
beast::secure_erase(ps.data(), ps.size());
return sk;
} }
LogicError ("generateSecretKey: unknown key type"); LogicError ("generateSecretKey: unknown key type");