@@ -693,7 +693,7 @@ fn from_hex(hex: &str, target: &mut [u8]) -> Result<usize, ()> {
693
693
}
694
694
695
695
696
- #[ cfg( test) ]
696
+ #[ cfg( all ( test, not ( feature = "fuzztarget" ) ) ) ]
697
697
mod tests {
698
698
use rand:: { RngCore , thread_rng} ;
699
699
use std:: str:: FromStr ;
@@ -1084,3 +1084,84 @@ mod benches {
1084
1084
} ) ;
1085
1085
}
1086
1086
}
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