mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-03 09:56:38 -05:00
crypto: require key on ChaCha20 initialization
This commit is contained in:
parent
44c11769a8
commit
7d1cd93234
5 changed files with 18 additions and 32 deletions
|
@ -40,11 +40,6 @@ void ChaCha20Aligned::SetKey(Span<const std::byte> key) noexcept
|
||||||
input[11] = 0;
|
input[11] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChaCha20Aligned::ChaCha20Aligned() noexcept
|
|
||||||
{
|
|
||||||
memset(input, 0, sizeof(input));
|
|
||||||
}
|
|
||||||
|
|
||||||
ChaCha20Aligned::~ChaCha20Aligned()
|
ChaCha20Aligned::~ChaCha20Aligned()
|
||||||
{
|
{
|
||||||
memory_cleanse(input, sizeof(input));
|
memory_cleanse(input, sizeof(input));
|
||||||
|
|
|
@ -34,7 +34,8 @@ public:
|
||||||
/** Block size (inputs/outputs to Keystream / Crypt should be multiples of this). */
|
/** Block size (inputs/outputs to Keystream / Crypt should be multiples of this). */
|
||||||
static constexpr unsigned BLOCKLEN{64};
|
static constexpr unsigned BLOCKLEN{64};
|
||||||
|
|
||||||
ChaCha20Aligned() noexcept;
|
/** For safety, disallow initialization without key. */
|
||||||
|
ChaCha20Aligned() noexcept = delete;
|
||||||
|
|
||||||
/** Initialize a cipher with specified 32-byte key. */
|
/** Initialize a cipher with specified 32-byte key. */
|
||||||
ChaCha20Aligned(Span<const std::byte> key) noexcept;
|
ChaCha20Aligned(Span<const std::byte> key) noexcept;
|
||||||
|
@ -84,7 +85,8 @@ public:
|
||||||
/** Expected key length in constructor and SetKey. */
|
/** Expected key length in constructor and SetKey. */
|
||||||
static constexpr unsigned KEYLEN = ChaCha20Aligned::KEYLEN;
|
static constexpr unsigned KEYLEN = ChaCha20Aligned::KEYLEN;
|
||||||
|
|
||||||
ChaCha20() noexcept = default;
|
/** For safety, disallow initialization without key. */
|
||||||
|
ChaCha20() noexcept = delete;
|
||||||
|
|
||||||
/** Initialize a cipher with specified 32-byte key. */
|
/** Initialize a cipher with specified 32-byte key. */
|
||||||
ChaCha20(Span<const std::byte> key) noexcept : m_aligned(key) {}
|
ChaCha20(Span<const std::byte> key) noexcept : m_aligned(key) {}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <random.h>
|
#include <random.h>
|
||||||
|
|
||||||
#include <compat/cpuid.h>
|
#include <compat/cpuid.h>
|
||||||
|
#include <crypto/chacha20.h>
|
||||||
#include <crypto/sha256.h>
|
#include <crypto/sha256.h>
|
||||||
#include <crypto/sha512.h>
|
#include <crypto/sha512.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
@ -606,10 +607,7 @@ void FastRandomContext::fillrand(Span<std::byte> output)
|
||||||
rng.Keystream(output);
|
rng.Keystream(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), bitbuf_size(0)
|
FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), rng(MakeByteSpan(seed)), bitbuf_size(0) {}
|
||||||
{
|
|
||||||
rng.SetKey(MakeByteSpan(seed));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Random_SanityCheck()
|
bool Random_SanityCheck()
|
||||||
{
|
{
|
||||||
|
@ -657,13 +655,13 @@ bool Random_SanityCheck()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), bitbuf_size(0)
|
static constexpr std::array<std::byte, ChaCha20::KEYLEN> ZERO_KEY{};
|
||||||
|
|
||||||
|
FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), rng(ZERO_KEY), bitbuf_size(0)
|
||||||
{
|
{
|
||||||
if (!fDeterministic) {
|
// Note that despite always initializing with ZERO_KEY, requires_seed is set to true if not
|
||||||
return;
|
// fDeterministic. That means the rng will be reinitialized with a secure random key upon first
|
||||||
}
|
// use.
|
||||||
static constexpr std::array<std::byte, ChaCha20::KEYLEN> ZERO{};
|
|
||||||
rng.SetKey(ZERO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FastRandomContext& FastRandomContext::operator=(FastRandomContext&& from) noexcept
|
FastRandomContext& FastRandomContext::operator=(FastRandomContext&& from) noexcept
|
||||||
|
|
|
@ -17,11 +17,9 @@ FUZZ_TARGET(crypto_chacha20)
|
||||||
{
|
{
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
|
|
||||||
ChaCha20 chacha20;
|
const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32);
|
||||||
if (fuzzed_data_provider.ConsumeBool()) {
|
ChaCha20 chacha20{MakeByteSpan(key)};
|
||||||
const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32);
|
|
||||||
chacha20 = ChaCha20{MakeByteSpan(key)};
|
|
||||||
}
|
|
||||||
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
|
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
|
||||||
CallOneOf(
|
CallOneOf(
|
||||||
fuzzed_data_provider,
|
fuzzed_data_provider,
|
||||||
|
|
|
@ -267,20 +267,13 @@ void ECRYPT_keystream_bytes(ECRYPT_ctx* x, u8* stream, u32 bytes)
|
||||||
|
|
||||||
FUZZ_TARGET(crypto_diff_fuzz_chacha20)
|
FUZZ_TARGET(crypto_diff_fuzz_chacha20)
|
||||||
{
|
{
|
||||||
static const unsigned char ZEROKEY[32] = {0};
|
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
|
|
||||||
ChaCha20 chacha20;
|
|
||||||
ECRYPT_ctx ctx;
|
ECRYPT_ctx ctx;
|
||||||
|
|
||||||
if (fuzzed_data_provider.ConsumeBool()) {
|
const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32);
|
||||||
const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32);
|
ChaCha20 chacha20{MakeByteSpan(key)};
|
||||||
chacha20 = ChaCha20{MakeByteSpan(key)};
|
ECRYPT_keysetup(&ctx, key.data(), key.size() * 8, 0);
|
||||||
ECRYPT_keysetup(&ctx, key.data(), key.size() * 8, 0);
|
|
||||||
} else {
|
|
||||||
// The default ChaCha20 constructor is equivalent to using the all-0 key.
|
|
||||||
ECRYPT_keysetup(&ctx, ZEROKEY, 256, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ECRYPT_keysetup() doesn't set the counter and nonce to 0 while SetKey() does
|
// ECRYPT_keysetup() doesn't set the counter and nonce to 0 while SetKey() does
|
||||||
static const uint8_t iv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
static const uint8_t iv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
Loading…
Add table
Reference in a new issue