From e13351c60ba72a63da43a1ba22f9df29c8f87338 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Fri, 23 Aug 2019 17:46:44 -0400 Subject: [PATCH] Add a static mut bool to prevent accidentally using fuzz functions --- src/ffi.rs | 29 ++++++++++++++++++++++++++++- src/recovery/ffi.rs | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ffi.rs b/src/ffi.rs index ca8fb1c4b..998c0dff4 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -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 } } @@ -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; @@ -408,29 +412,35 @@ 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::() } /// 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::() } /// 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; } @@ -438,6 +448,7 @@ mod fuzz_dummy { 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 } @@ -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 => { @@ -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 { @@ -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); @@ -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; @@ -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 @@ -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; } @@ -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; } @@ -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 @@ -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 { @@ -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); @@ -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); @@ -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); @@ -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); @@ -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); @@ -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 { @@ -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; } diff --git a/src/recovery/ffi.rs b/src/recovery/ffi.rs index 6b6e1f94a..dea8a4812 100644 --- a/src/recovery/ffi.rs +++ b/src/recovery/ffi.rs @@ -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; }