Skip to content

Commit 30193f5

Browse files
committed
Add tests for the CRYPTO_VAR_LOCK variable
1 parent 3a9b470 commit 30193f5

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ script:
3232
- cargo test --verbose --features=rand
3333
- cargo test --verbose --features="rand serde"
3434
- cargo test --verbose --features="rand serde recovery endomorphism"
35+
- cargo test --lib --features=fuzztarget
3536
- cargo build --verbose
3637
- cargo test --verbose
3738
- cargo build --verbose --release

src/ecdh.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl ops::Index<ops::RangeFull> for SharedSecret {
9696
}
9797
}
9898

99-
#[cfg(test)]
99+
#[cfg(all(test, not(feature = "fuzztarget")))]
100100
mod tests {
101101
use rand::thread_rng;
102102
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

+82-1
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ fn from_hex(hex: &str, target: &mut [u8]) -> Result<usize, ()> {
693693
}
694694

695695

696-
#[cfg(test)]
696+
#[cfg(all(test, not(feature = "fuzztarget")))]
697697
mod tests {
698698
use rand::{RngCore, thread_rng};
699699
use std::str::FromStr;
@@ -1084,3 +1084,84 @@ mod benches {
10841084
});
10851085
}
10861086
}
1087+
1088+
#[cfg(all(test, feature = "fuzztarget"))]
1089+
mod test_fuzz {
1090+
use super::*;
1091+
use std::str::FromStr;
1092+
use std::panic::{self, UnwindSafe};
1093+
use std::sync::MutexGuard;
1094+
1095+
1096+
pub fn lock_crypto_var() -> MutexGuard<'static, ()> {
1097+
use std::sync::{Mutex, Once, ONCE_INIT};
1098+
1099+
static mut CRYPTO_VAR_LOCK: Option<Mutex<()>> = None;
1100+
static INIT_CONTEXT: Once = ONCE_INIT;
1101+
1102+
INIT_CONTEXT.call_once(|| unsafe {
1103+
CRYPTO_VAR_LOCK = Some(Default::default());
1104+
});
1105+
unsafe { CRYPTO_VAR_LOCK.as_ref().unwrap().lock().unwrap() }
1106+
}
1107+
1108+
1109+
1110+
pub fn crashed_for_fuzz<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> bool {
1111+
let description = "Tried fuzzing without setting the UNSAFE_CRYPTO_FUZZING variable";
1112+
if let Err(e) = panic::catch_unwind(f) {
1113+
if let Some(st) = e.downcast_ref::<&str>() {
1114+
return st.contains(description);
1115+
}
1116+
}
1117+
false
1118+
}
1119+
1120+
#[test]
1121+
fn fuzz_not_set_var() {
1122+
let _lock = lock_crypto_var();
1123+
unsafe {ffi::UNSAFE_CRYPTO_FUZZING = false};
1124+
assert!(crashed_for_fuzz(|| SecretKey::from_slice(&[2; 32])));
1125+
assert!(crashed_for_fuzz(|| PublicKey::from_slice(&[2; 33])));
1126+
assert!(crashed_for_fuzz(|| Signature::from_compact(&[3; 64])));
1127+
assert!(crashed_for_fuzz(|| Secp256k1::new()));
1128+
assert!(crashed_for_fuzz(|| {
1129+
let mut sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1130+
let _ = sec.add_assign(&[2u8; 32]);
1131+
}));
1132+
assert!(crashed_for_fuzz(|| {
1133+
let mut sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1134+
let _ = sec.mul_assign(&[2u8; 32]);
1135+
}));
1136+
assert!(crashed_for_fuzz(|| {
1137+
let sig: Signature = unsafe { std::mem::transmute::<_, ffi::Signature>([3u8; 64]).into() };
1138+
let _ = sig.serialize_compact();
1139+
}));
1140+
1141+
assert!(crashed_for_fuzz(|| {
1142+
let pubkey1: PublicKey = unsafe { std::mem::transmute::<_, ffi::PublicKey>([3u8; 64]).into() };
1143+
let pubkey2: PublicKey = unsafe { std::mem::transmute::<_, ffi::PublicKey>([5u8; 64]).into() };
1144+
let _ = pubkey1.combine(&pubkey2);
1145+
}));
1146+
}
1147+
1148+
#[test]
1149+
fn fuzz_set_var_not_crash() {
1150+
let _lock = lock_crypto_var();
1151+
unsafe {ffi::UNSAFE_CRYPTO_FUZZING = true;}
1152+
let _ = SecretKey::from_slice(&[2; 32]);
1153+
let _ = PublicKey::from_slice(&[2; 33]);
1154+
let _ = Signature::from_compact(&[3; 64]);
1155+
let _ = Secp256k1::new();
1156+
let mut sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1157+
let _ = sec.add_assign(&[2u8; 32]);
1158+
let mut sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1159+
let _ = sec.mul_assign(&[2u8; 32]);
1160+
let sig: Signature = unsafe { std::mem::transmute::<_, ffi::Signature>([3u8; 64]).into() };
1161+
let _ = sig.serialize_compact();
1162+
let pubkey1: PublicKey = unsafe { std::mem::transmute::<_, ffi::PublicKey>([3u8; 64]).into() };
1163+
let pubkey2: PublicKey = unsafe { std::mem::transmute::<_, ffi::PublicKey>([5u8; 64]).into() };
1164+
let _ = pubkey1.combine(&pubkey2);
1165+
}
1166+
}
1167+

0 commit comments

Comments
 (0)