From 39f91351046bdff30b153f8442b562a3abe0ac82 Mon Sep 17 00:00:00 2001 From: Nik Bougalis Date: Wed, 6 Sep 2017 10:13:40 -0700 Subject: [PATCH] Securely erase memory & reduce public API --- .../crypto/impl/GenerateDeterministicKey.cpp | 12 +-- src/ripple/protocol/SecretKey.h | 24 ------ src/ripple/protocol/Serializer.h | 5 +- src/ripple/protocol/impl/SecretKey.cpp | 75 ++++++++++++------- 4 files changed, 55 insertions(+), 61 deletions(-) diff --git a/src/ripple/crypto/impl/GenerateDeterministicKey.cpp b/src/ripple/crypto/impl/GenerateDeterministicKey.cpp index a2265af38fc..80599debcc6 100644 --- a/src/ripple/crypto/impl/GenerateDeterministicKey.cpp +++ b/src/ripple/crypto/impl/GenerateDeterministicKey.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -74,8 +75,6 @@ copy_uint32 (FwdIt out, std::uint32_t v) *out = v & 0xff; } -// #define EC_DEBUG - // Functions to add support for deterministic EC keys // --> seed @@ -94,12 +93,12 @@ static bignum generateRootDeterministicKey (uint128 const& seed) std::copy(seed.begin(), seed.end(), buf.begin()); copy_uint32 (buf.begin() + 16, seq++); 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()); - root.zero(); // security erase + beast::secure_erase(root.data(), root.size()); } while (privKey.is_zero() || privKey >= secp256k1curve.order); - + beast::secure_erase(&seq, sizeof(seq)); 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() + 37, subSeq++); 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()); + beast::secure_erase(root.data(), root.size()); } while (result.is_zero() || result >= order); diff --git a/src/ripple/protocol/SecretKey.h b/src/ripple/protocol/SecretKey.h index 20204479cca..6174ed40ecb 100644 --- a/src/ripple/protocol/SecretKey.h +++ b/src/ripple/protocol/SecretKey.h @@ -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 - 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 */ template <> boost::optional diff --git a/src/ripple/protocol/Serializer.h b/src/ripple/protocol/Serializer.h index e389b72bee8..094898415dd 100644 --- a/src/ripple/protocol/Serializer.h +++ b/src/ripple/protocol/Serializer.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -198,8 +199,8 @@ class Serializer } void secureErase () { - memset (& (mData.front ()), 0, mData.size ()); - erase (); + beast::secure_erase(mData.data(), mData.size()); + mData.clear (); } void erase () { diff --git a/src/ripple/protocol/impl/SecretKey.cpp b/src/ripple/protocol/impl/SecretKey.cpp index 0a8dbca1e52..d40586c3863 100644 --- a/src/ripple/protocol/impl/SecretKey.cpp +++ b/src/ripple/protocol/impl/SecretKey.cpp @@ -56,35 +56,46 @@ SecretKey::to_string() const } //------------------------------------------------------------------------------ - -Generator::Generator (Seed const& seed) +/** Produces a sequence of secp256k1 key pairs. */ +class Generator { - uint128 ui; - std::memcpy(ui.data(), - seed.data(), seed.size()); - gen_ = generateRootDeterministicPublicKey(ui); -} +private: + Blob gen_; // VFALCO compile time size? -std::pair -Generator::operator()(Seed const& seed, std::size_t ordinal) const -{ - 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 }; -} +public: + explicit + Generator (Seed const& seed) + { + // FIXME: Avoid copying the seed into a uint128 key only to have + // generateRootDeterministicPublicKey copy out of it. + uint128 ui; + std::memcpy(ui.data(), + seed.data(), seed.size()); + gen_ = generateRootDeterministicPublicKey(ui); + } -PublicKey -Generator::operator()(std::size_t ordinal) const -{ - auto gpk = generatePublicDeterministicKey(gen_, ordinal); - return PublicKey(Slice{ gpk.data(), gpk.size() }); -} + /** Generate the nth key pair. + + The seed is required to produce the private key. + */ + std::pair + 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) { - auto const key = sha512Half_s(Slice( + auto key = sha512Half_s(Slice( 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) { + // FIXME: Avoid copying the seed into a uint128 key only to have + // generateRootDeterministicPrivateKey copy out of it. uint128 ps; std::memcpy(ps.data(), seed.data(), seed.size()); auto const upk = 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");