Stub out Sha2 calls when fuzzing to mask all but the first byte

This commit is contained in:
Matt Corallo 2018-03-20 12:05:33 -04:00
parent d445eaa8c3
commit 6826d8f35c
7 changed files with 81 additions and 5 deletions

View File

@ -17,6 +17,7 @@ path = "src/lib.rs"
[features]
bitcoinconsenus = ["bitcoinconsensus"]
fuzztarget = ["secp256k1/fuzztarget"]
[dependencies]
bitcoin-bech32 = "0.5.1"

View File

@ -28,7 +28,6 @@ use std::default::Default;
use std::{error, fmt};
use crypto::digest::Digest;
use crypto::sha2::Sha256;
use serde;
use blockdata::opcodes;
@ -39,6 +38,9 @@ use util::hash::Hash160;
#[cfg(feature="bitcoinconsensus")] use std::convert;
#[cfg(feature="bitcoinconsensus")] use util::hash::Sha256dHash;
#[cfg(feature="fuzztarget")] use util::sha2::Sha256;
#[cfg(not(feature="fuzztarget"))] use crypto::sha2::Sha256;
#[derive(Clone, PartialEq, Eq, Hash)]
/// A Bitcoin script
pub struct Script(Box<[u8]>);

View File

@ -28,14 +28,15 @@ use crypto::digest::Digest;
use crypto::hmac::Hmac;
use crypto::mac::Mac;
use crypto::ripemd160::Ripemd160;
use crypto::sha2::Sha256;
use crypto::sha2::Sha512;
use secp256k1::key::{PublicKey, SecretKey};
use secp256k1::{self, Secp256k1};
use network::constants::Network;
use util::base58;
#[cfg(feature="fuzztarget")] use util::sha2::{Sha256, Sha512};
#[cfg(not(feature="fuzztarget"))] use crypto::sha2::{Sha256, Sha512};
/// A chain code
pub struct ChainCode([u8; 32]);
impl_array_newtype!(ChainCode, u8, 32);

View File

@ -20,7 +20,7 @@
use secp256k1::{self, Secp256k1};
use secp256k1::key::{PublicKey, SecretKey};
use blockdata::{opcodes, script};
use crypto::{hmac, sha2};
use crypto::hmac;
use crypto::mac::Mac;
use std::{error, fmt};
@ -28,6 +28,9 @@ use std::{error, fmt};
use network::constants::Network;
use util::{address, hash};
#[cfg(feature="fuzztarget")] use util::sha2;
#[cfg(not(feature="fuzztarget"))] use crypto::sha2;
/// Encoding of "pubkey here" in script; from bitcoin core `src/script/script.h`
static PUBKEY: u8 = 0xFE;

View File

@ -26,13 +26,15 @@ use serde;
use byteorder::{LittleEndian, WriteBytesExt};
use crypto::digest::Digest;
use crypto::sha2::Sha256;
use crypto::ripemd160::Ripemd160;
use network::encodable::{ConsensusDecodable, ConsensusEncodable};
use network::serialize::{SimpleEncoder, RawEncoder, BitcoinHash};
use util::uint::Uint256;
#[cfg(feature="fuzztarget")] use util::sha2::Sha256;
#[cfg(not(feature="fuzztarget"))] use crypto::sha2::Sha256;
/// Hex deserialization error
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum HexError {

View File

@ -28,6 +28,9 @@ pub mod iter;
pub mod misc;
pub mod uint;
#[cfg(feature = "fuzztarget")]
pub mod sha2;
use std::{error, fmt, io};
use bitcoin_bech32;

64
src/util/sha2.rs Normal file
View File

@ -0,0 +1,64 @@
//! fuzztarget-only Sha2 context with a dummy Sha256 and Sha512 hashers.
use crypto::digest::Digest;
use crypto::sha2;
#[derive(Clone, Copy)]
/// Dummy Sha256 that hashes the input, but only returns the first byte of output, masking the
/// rest to 0s.
pub struct Sha256 {
state: sha2::Sha256,
}
impl Sha256 {
/// Constructs a new dummy Sha256 context
pub fn new() -> Sha256 {
Sha256 {
state: sha2::Sha256::new(),
}
}
}
impl Digest for Sha256 {
fn result(&mut self, data: &mut [u8]) {
self.state.result(data);
for i in 1..32 {
data[i] = 0;
}
}
fn input(&mut self, data: &[u8]) { self.state.input(data); }
fn reset(&mut self) { self.state.reset(); }
fn output_bits(&self) -> usize { self.state.output_bits() }
fn block_size(&self) -> usize { self.state.block_size() }
}
#[derive(Clone, Copy)]
/// Dummy Sha512 that hashes the input, but only returns the first byte of output, masking the
/// rest to 0s.
pub struct Sha512 {
state: sha2::Sha512,
}
impl Sha512 {
/// Constructs a new dummy Sha512 context
pub fn new() -> Sha512 {
Sha512 {
state: sha2::Sha512::new(),
}
}
}
impl Digest for Sha512 {
fn result(&mut self, data: &mut [u8]) {
self.state.result(data);
for i in 1..64 {
data[i] = 0;
}
}
fn input(&mut self, data: &[u8]) { self.state.input(data); }
fn reset(&mut self) { self.state.reset(); }
fn output_bits(&self) -> usize { self.state.output_bits() }
fn block_size(&self) -> usize { self.state.block_size() }
}