Skip to content

Commit c29481e

Browse files
committed
Add tests for the CRYPTO_VAR_LOCK variable
1 parent 5e415b6 commit c29481e

File tree

6 files changed

+86
-7
lines changed

6 files changed

+86
-7
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ script:
3838
- cargo test --verbose --features="rand rand-std"
3939
- cargo test --verbose --features="rand serde"
4040
- cargo test --verbose --features="rand serde recovery endomorphism"
41+
- cargo test --verbose --lib --features=fuzztarget
4142
- cargo build --verbose
4243
- cargo test --verbose
4344
- cargo build --verbose --release

secp256k1-sys/src/recovery.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,10 @@ mod fuzz_dummy {
7979
use self::std::ptr;
8080
use super::RecoverableSignature;
8181
use types::*;
82-
use ::{Signature, Context, PublicKey, NonceFn, secp256k1_ec_seckey_verify,
83-
SECP256K1_START_NONE, SECP256K1_START_VERIFY, SECP256K1_START_SIGN};
84-
82+
use ::{
83+
secp256k1_ec_seckey_verify, Context, NonceFn, PublicKey, Signature, SECP256K1_START_NONE,
84+
SECP256K1_START_SIGN, SECP256K1_START_VERIFY, UNSAFE_CRYPTO_FUZZING, UNSAFE_CRYPTO_WARNING,
85+
};
8586
pub unsafe fn secp256k1_ecdsa_recoverable_signature_parse_compact(_cx: *const Context, _sig: *mut RecoverableSignature,
8687
_input64: *const c_uchar, _recid: c_int)
8788
-> c_int {

src/ecdh.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ impl SharedSecret {
162162
}
163163
}
164164

165-
#[cfg(test)]
165+
#[cfg(all(test, not(feature = "fuzztarget")))]
166166
mod tests {
167167
use rand::thread_rng;
168168
use super::SharedSecret;

src/key.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ impl<'de> ::serde::Deserialize<'de> for PublicKey {
443443
}
444444
}
445445

446-
#[cfg(test)]
446+
#[cfg(all(test, not(feature = "fuzztarget")))]
447447
mod test {
448448
use Secp256k1;
449449
use from_hex;

src/lib.rs

+78-1
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ fn from_hex(hex: &str, target: &mut [u8]) -> Result<usize, ()> {
707707
}
708708

709709

710-
#[cfg(test)]
710+
#[cfg(all(test, not(feature = "fuzztarget")))]
711711
mod tests {
712712
use rand::{RngCore, thread_rng};
713713
use std::str::FromStr;
@@ -1160,3 +1160,80 @@ mod benches {
11601160
});
11611161
}
11621162
}
1163+
1164+
#[cfg(all(test, feature = "fuzztarget"))]
1165+
mod test_fuzz {
1166+
use super::*;
1167+
use std::str::FromStr;
1168+
use std::panic::{self, UnwindSafe};
1169+
use std::mem;
1170+
1171+
1172+
pub fn crashed_for_fuzz<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> bool {
1173+
if let Err(e) = panic::catch_unwind(f) {
1174+
if let Some(st) = e.downcast_ref::<&str>() {
1175+
return st.contains(ffi::UNSAFE_CRYPTO_WARNING);
1176+
}
1177+
}
1178+
false
1179+
}
1180+
1181+
fn fuzz_not_set_var() {
1182+
unsafe {ffi::UNSAFE_CRYPTO_FUZZING = false};
1183+
let mut raw_fake_context: ffi::Context = unsafe {mem::transmute(VerifyOnly::FLAGS | SignOnly::FLAGS)};
1184+
let fake_context: Secp256k1<All> = Secp256k1 {
1185+
ctx: &mut raw_fake_context,
1186+
phantom: PhantomData,
1187+
buf: ptr::null_mut::<[u8;0]>() as *mut [u8]
1188+
};
1189+
let msg = Message::from_slice(&[1u8; 32]).unwrap();
1190+
let sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1191+
let sig: Signature = unsafe { std::mem::transmute::<_, ffi::Signature>([3u8; 64]).into() };
1192+
1193+
assert!(crashed_for_fuzz(|| SecretKey::from_slice(&[2; 32])));
1194+
assert!(crashed_for_fuzz(|| PublicKey::from_slice(&[2; 33])));
1195+
assert!(crashed_for_fuzz(|| Signature::from_compact(&[3; 64])));
1196+
assert!(crashed_for_fuzz(|| Secp256k1::new()));
1197+
assert!(crashed_for_fuzz(|| sec.clone().add_assign(&[2u8; 32])));
1198+
assert!(crashed_for_fuzz(|| sec.clone().mul_assign(&[2u8; 32])));
1199+
assert!(crashed_for_fuzz(|| sig.serialize_compact()));
1200+
assert!(crashed_for_fuzz(|| fake_context.sign(&msg, &sec)));
1201+
#[cfg(feature = "recovery")]
1202+
{
1203+
assert!(crashed_for_fuzz(||fake_context.sign_recoverable(&msg, &sec)));
1204+
}
1205+
assert!(crashed_for_fuzz(|| drop(fake_context)));
1206+
}
1207+
1208+
fn fuzz_set_var_not_crash() {
1209+
unsafe {ffi::UNSAFE_CRYPTO_FUZZING = true;}
1210+
let context = Secp256k1::new();
1211+
let msg = Message::from_slice(&[1u8; 32]).unwrap();
1212+
let _ = SecretKey::from_slice(&[2; 32]);
1213+
let _ = PublicKey::from_slice(&[2; 33]);
1214+
let _ = Signature::from_compact(&[3; 64]);
1215+
let _ = Secp256k1::new();
1216+
let mut sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1217+
let _ = sec.add_assign(&[2u8; 32]);
1218+
let mut sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1219+
let _ = sec.mul_assign(&[2u8; 32]);
1220+
let sig: Signature = unsafe { std::mem::transmute::<_, ffi::Signature>([3u8; 64]).into() };
1221+
let _ = sig.serialize_compact();
1222+
let pubkey1: PublicKey = unsafe { mem::transmute::<_, ffi::PublicKey>([3u8; 64]).into() };
1223+
let pubkey2: PublicKey = unsafe { mem::transmute::<_, ffi::PublicKey>([5u8; 64]).into() };
1224+
let _ = pubkey1.combine(&pubkey2);
1225+
let sig = context.sign(&msg, &sec);
1226+
assert_eq!(context.verify(&msg, &sig, &pubkey1).unwrap_err(), Error::IncorrectSignature);
1227+
1228+
#[cfg(feature = "recovery")]
1229+
{
1230+
let _ = context.sign_recoverable(&msg, &sec);
1231+
}
1232+
}
1233+
1234+
#[test]
1235+
fn test_fuzz_setting_var() {
1236+
fuzz_not_set_var();
1237+
fuzz_set_var_not_crash();
1238+
}
1239+
}

src/recovery.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl<C: Verification> Secp256k1<C> {
191191
}
192192

193193

194-
#[cfg(test)]
194+
#[cfg(all(test, not(feature = "fuzztarget")))]
195195
mod tests {
196196
use rand::{RngCore, thread_rng};
197197

0 commit comments

Comments
 (0)