Skip to content

Commit

Permalink
Add a static mut bool to prevent accidentally using fuzz functions
Browse files Browse the repository at this point in the history
  • Loading branch information
elichai committed Aug 24, 2019
1 parent 4e69dcc commit e13351c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
29 changes: 28 additions & 1 deletion src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub type EcdhHashFn = unsafe extern "C" fn(
#[cfg(feature = "fuzztarget")]
impl Context {
pub fn flags(&self) -> u32 {
unsafe {assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING); }
self.0 as u32
}
}
Expand Down Expand Up @@ -399,6 +400,9 @@ mod fuzz_dummy {
use self::std::{ptr, mem};
use self::std::boxed::Box;

pub static mut UNSAFE_CRYPTO_FUZZING: bool = false;
pub const UNSAFE_CRYPTO_WARNING: &str = "Tried fuzzing without setting the UNSAFE_CRYPTO_FUZZING variable";

extern "C" {
pub static secp256k1_ecdh_hash_function_default: EcdhHashFn;
pub static secp256k1_nonce_function_rfc6979: NonceFn;
Expand All @@ -408,36 +412,43 @@ mod fuzz_dummy {
// Contexts
/// Creates a dummy context, tracking flags to ensure proper calling semantics
pub unsafe fn secp256k1_context_preallocated_create(_ptr: *mut c_void, flags: c_uint) -> *mut Context {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
let b = Box::new(Context(flags as i32));
Box::into_raw(b)
}

/// Return dummy size of context struct.
pub unsafe fn secp256k1_context_preallocated_size(_flags: c_uint) -> usize {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
mem::size_of::<Context>()
}

/// Return dummy size of context struct.
pub unsafe fn secp256k1_context_preallocated_clone_size(cx: *mut Context) -> usize {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
mem::size_of::<Context>()
}

/// Copies a dummy context
pub unsafe fn secp256k1_context_preallocated_clone(cx: *const Context, prealloc: *mut c_void) -> *mut Context {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
let ret = prealloc as *mut Context;
*ret = (*cx).clone();
ret
}

/// "Destroys" a dummy context
pub unsafe fn secp256k1_context_preallocated_destroy(cx: *mut Context) {
pub unsafe fn secp256k1_context_preallocated_destroy(cx: *mut Context)
{
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
(*cx).0 = 0;
}

/// Asserts that cx is properly initialized
pub unsafe fn secp256k1_context_randomize(cx: *mut Context,
_seed32: *const c_uchar)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
1
}
Expand All @@ -454,6 +465,7 @@ mod fuzz_dummy {
pub unsafe fn secp256k1_ec_pubkey_parse(cx: *const Context, pk: *mut PublicKey,
input: *const c_uchar, in_len: usize)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
match in_len {
33 => {
Expand Down Expand Up @@ -482,6 +494,7 @@ mod fuzz_dummy {
out_len: *mut usize, pk: *const PublicKey,
compressed: c_uint)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if test_pk_validate(cx, pk) != 1 { return 0; }
if compressed == SECP256K1_SER_COMPRESSED {
Expand Down Expand Up @@ -513,6 +526,7 @@ mod fuzz_dummy {
pub unsafe fn secp256k1_ecdsa_signature_parse_compact(cx: *const Context, sig: *mut Signature,
input64: *const c_uchar)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, input64.offset(32)) != 1 { return 0; } // sig should be msg32||sk
ptr::copy(input64, (*sig).0[..].as_mut_ptr(), 64);
Expand All @@ -529,6 +543,7 @@ mod fuzz_dummy {
pub unsafe fn secp256k1_ecdsa_signature_serialize_der(cx: *const Context, output: *mut c_uchar,
out_len: *mut usize, sig: *const Signature)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);

let mut len_r = 33;
Expand Down Expand Up @@ -567,6 +582,7 @@ mod fuzz_dummy {
pub unsafe fn secp256k1_ecdsa_signature_serialize_compact(cx: *const Context, output64: *mut c_uchar,
sig: *const Signature)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
ptr::copy((*sig).0[..].as_ptr(), output64, 64);
1
Expand All @@ -585,6 +601,7 @@ mod fuzz_dummy {
msg32: *const c_uchar,
pk: *const PublicKey)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
assert!((*cx).0 as u32 & SECP256K1_START_VERIFY == SECP256K1_START_VERIFY);
if test_pk_validate(cx, pk) != 1 { return 0; }
Expand All @@ -608,6 +625,7 @@ mod fuzz_dummy {
_noncefn: NonceFn,
_noncedata: *const c_void)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
assert!((*cx).0 as u32 & SECP256K1_START_SIGN == SECP256K1_START_SIGN);
if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
Expand All @@ -620,6 +638,7 @@ mod fuzz_dummy {
/// Checks that pk != 0xffff...ffff and pk[0..32] == pk[32..64]
pub unsafe fn test_pk_validate(cx: *const Context,
pk: *const PublicKey) -> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if (*pk).0[0..32] != (*pk).0[32..64] || secp256k1_ec_seckey_verify(cx, (*pk).0[0..32].as_ptr()) == 0 {
0
Expand All @@ -631,6 +650,7 @@ mod fuzz_dummy {
/// Checks that sk != 0xffff...ffff
pub unsafe fn secp256k1_ec_seckey_verify(cx: *const Context,
sk: *const c_uchar) -> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
let mut res = 0;
for i in 0..32 {
Expand All @@ -642,6 +662,7 @@ mod fuzz_dummy {
/// Sets pk to sk||sk
pub unsafe fn secp256k1_ec_pubkey_create(cx: *const Context, pk: *mut PublicKey,
sk: *const c_uchar) -> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
ptr::copy(sk, (*pk).0[0..32].as_mut_ptr(), 32);
Expand All @@ -657,6 +678,7 @@ mod fuzz_dummy {
sk: *mut c_uchar,
tweak: *const c_uchar)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
ptr::copy(tweak.offset(16), sk.offset(16), 16);
Expand All @@ -669,6 +691,7 @@ mod fuzz_dummy {
pk: *mut PublicKey,
tweak: *const c_uchar)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if test_pk_validate(cx, pk) != 1 { return 0; }
ptr::copy(tweak.offset(16), (*pk).0[16..32].as_mut_ptr(), 16);
Expand All @@ -683,6 +706,7 @@ mod fuzz_dummy {
sk: *mut c_uchar,
tweak: *const c_uchar)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
ptr::copy(tweak.offset(16), sk.offset(16), 16);
Expand All @@ -695,6 +719,7 @@ mod fuzz_dummy {
pk: *mut PublicKey,
tweak: *const c_uchar)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if test_pk_validate(cx, pk) != 1 { return 0; }
ptr::copy(tweak.offset(16), (*pk).0[16..32].as_mut_ptr(), 16);
Expand All @@ -709,6 +734,7 @@ mod fuzz_dummy {
ins: *const *const PublicKey,
n: c_int)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
assert!(n <= 32 && n >= 0); //TODO: Remove this restriction?
for i in 0..n {
Expand All @@ -730,6 +756,7 @@ mod fuzz_dummy {
_hashfp: EcdhHashFn,
_data: *mut c_void,
) -> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).0 as u32 & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
if secp256k1_ec_seckey_verify(cx, scalar) != 1 { return 0; }

Expand Down
1 change: 1 addition & 0 deletions src/recovery/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ mod fuzz_dummy {
_noncefn: NonceFn,
_noncedata: *const c_void)
-> c_int {
assert!(UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING);
assert!(!cx.is_null() && (*cx).flags() & !(SECP256K1_START_NONE | SECP256K1_START_VERIFY | SECP256K1_START_SIGN) == 0);
assert!((*cx).flags() & SECP256K1_START_SIGN == SECP256K1_START_SIGN);
if secp256k1_ec_seckey_verify(cx, sk) != 1 { return 0; }
Expand Down

0 comments on commit e13351c

Please sign in to comment.