Skip to content

Commit 1f2cb92

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

File tree

4 files changed

+82
-3
lines changed

4 files changed

+82
-3
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 79 additions & 1 deletion
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,81 @@ 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::{Mutex, Once, MutexGuard};
1094+
1095+
1096+
pub fn lock_crypto_var() -> MutexGuard<'static, ()> {
1097+
static mut CRYPTO_VAR_LOCK: Option<Mutex<()>> = None;
1098+
static INIT_CONTEXT: Once = Once::new();
1099+
INIT_CONTEXT.call_once(|| unsafe {
1100+
CRYPTO_VAR_LOCK = Some(Default::default());
1101+
});
1102+
unsafe { CRYPTO_VAR_LOCK.as_ref().unwrap().lock().unwrap() }
1103+
}
1104+
1105+
1106+
1107+
pub fn crashed_for_fuzz<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> bool {
1108+
let description = "Tried fuzzing without setting the UNSAFE_CRYPTO_FUZZING variable";
1109+
if let Err(e) = panic::catch_unwind(f) {
1110+
if let Some(st) = e.downcast_ref::<&str>() {
1111+
return st.contains(description);
1112+
}
1113+
}
1114+
false
1115+
}
1116+
1117+
#[test]
1118+
fn fuzz_not_set_var() {
1119+
let _lock = lock_crypto_var();
1120+
unsafe {ffi::UNSAFE_CRYPTO_FUZZING = false};
1121+
assert!(crashed_for_fuzz(|| SecretKey::from_slice(&[2; 32])));
1122+
assert!(crashed_for_fuzz(|| PublicKey::from_slice(&[2; 33])));
1123+
assert!(crashed_for_fuzz(|| Signature::from_compact(&[3; 64])));
1124+
assert!(crashed_for_fuzz(|| Secp256k1::new()));
1125+
assert!(crashed_for_fuzz(|| {
1126+
let mut sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1127+
let _ = sec.add_assign(&[2u8; 32]);
1128+
}));
1129+
assert!(crashed_for_fuzz(|| {
1130+
let mut sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1131+
let _ = sec.mul_assign(&[2u8; 32]);
1132+
}));
1133+
assert!(crashed_for_fuzz(|| {
1134+
let sig: Signature = unsafe { std::mem::transmute::<_, ffi::Signature>([3u8; 64]).into() };
1135+
let _ = sig.serialize_compact();
1136+
}));
1137+
1138+
assert!(crashed_for_fuzz(|| {
1139+
let pubkey1: PublicKey = unsafe { std::mem::transmute::<_, ffi::PublicKey>([3u8; 64]).into() };
1140+
let pubkey2: PublicKey = unsafe { std::mem::transmute::<_, ffi::PublicKey>([5u8; 64]).into() };
1141+
let _ = pubkey1.combine(&pubkey2);
1142+
}));
1143+
}
1144+
1145+
#[test]
1146+
fn fuzz_set_var_not_crash() {
1147+
let _lock = lock_crypto_var();
1148+
unsafe {ffi::UNSAFE_CRYPTO_FUZZING = true;}
1149+
let _ = SecretKey::from_slice(&[2; 32]);
1150+
let _ = PublicKey::from_slice(&[2; 33]);
1151+
let _ = Signature::from_compact(&[3; 64]);
1152+
let _ = Secp256k1::new();
1153+
let mut sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1154+
let _ = sec.add_assign(&[2u8; 32]);
1155+
let mut sec = SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap();
1156+
let _ = sec.mul_assign(&[2u8; 32]);
1157+
let sig: Signature = unsafe { std::mem::transmute::<_, ffi::Signature>([3u8; 64]).into() };
1158+
let _ = sig.serialize_compact();
1159+
let pubkey1: PublicKey = unsafe { std::mem::transmute::<_, ffi::PublicKey>([3u8; 64]).into() };
1160+
let pubkey2: PublicKey = unsafe { std::mem::transmute::<_, ffi::PublicKey>([5u8; 64]).into() };
1161+
let _ = pubkey1.combine(&pubkey2);
1162+
}
1163+
}
1164+

0 commit comments

Comments
 (0)