@@ -17,6 +17,7 @@ use crate::hash::Type as MdType;
1717use crate :: private:: UnsafeFrom ;
1818use crate :: rng:: Random ;
1919use core:: convert:: TryInto ;
20+ use core:: ops:: Sub ;
2021use core:: ptr;
2122
2223use byteorder:: { BigEndian , ByteOrder } ;
@@ -691,6 +692,13 @@ impl Pk {
691692 return Err ( Error :: RsaOutputTooLarge ) ;
692693 }
693694
695+ // Don't process outside of {2, ..., n-2}
696+ let nm1 = self . rsa_public_modulus ( ) ?. sub ( & Mpi :: new ( 1 ) ?) ?;
697+ let c_mpi = Mpi :: from_binary ( cipher) ?;
698+ if c_mpi <= Mpi :: new ( 1 ) . unwrap ( ) || c_mpi >= nm1 {
699+ return Err ( Error :: MpiBadInputData ) ;
700+ }
701+
694702 unsafe {
695703 rsa_private ( ctx, Some ( F :: call) , rng. data_ptr ( ) , cipher. as_ptr ( ) , plain. as_mut_ptr ( ) ) . into_result ( ) ?;
696704 } ;
@@ -1023,6 +1031,7 @@ mod tests {
10231031 use super :: * ;
10241032 use crate :: hash:: { MdInfo , Type } ;
10251033 use crate :: pk:: Type as PkType ;
1034+ use core:: ops:: Sub ;
10261035
10271036 // This is test data that must match library output *exactly*
10281037 const TEST_PEM : & ' static str = "-----BEGIN RSA PRIVATE KEY-----
@@ -1470,4 +1479,38 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi
14701479 assert ! ( pk. custom_public_key( ) . is_err( ) ) ;
14711480 assert ! ( pk. custom_private_key( ) . is_err( ) ) ;
14721481 }
1482+
1483+ #[ test]
1484+ fn fips_rsadp_bounds ( ) {
1485+ let rng = & mut crate :: test_support:: rand:: test_rng ( ) ;
1486+ let ( bitlen, exp) = ( 2048 , 0x10001 ) ;
1487+ let mut pk = Pk :: generate_rsa ( rng, bitlen, exp) . unwrap ( ) ;
1488+ pk. set_options ( Options :: Rsa {
1489+ padding : RsaPadding :: None ,
1490+ } ) ;
1491+
1492+ const LEN : usize = 256 ;
1493+
1494+ // Decrypting anything out of {2, n-2} should fail
1495+ let expected_err = Error :: MpiBadInputData ;
1496+
1497+ let mut pt = [ 0x00 ; LEN ] ;
1498+
1499+ let _0 = Mpi :: new ( 0 ) . unwrap ( ) ;
1500+ let _1 = Mpi :: new ( 1 ) . unwrap ( ) ;
1501+ let _2 = Mpi :: new ( 2 ) . unwrap ( ) ;
1502+ let n = pk. rsa_public_modulus ( ) . unwrap ( ) ;
1503+ let nm1 = pk. rsa_public_modulus ( ) . unwrap ( ) . sub ( & Mpi :: new ( 1 ) . unwrap ( ) ) . unwrap ( ) ;
1504+ let nm2 = pk. rsa_public_modulus ( ) . unwrap ( ) . sub ( & Mpi :: new ( 2 ) . unwrap ( ) ) . unwrap ( ) ;
1505+ for c in [ _0, _1, nm1, n] {
1506+ let ct = c. to_binary_padded ( LEN ) . unwrap ( ) ;
1507+ let l = pk. decrypt ( & ct, & mut pt, rng) ;
1508+ assert_eq ! ( l. unwrap_err( ) , expected_err) ;
1509+ }
1510+ for c in [ _2, nm2] {
1511+ let ct = c. to_binary_padded ( LEN ) . unwrap ( ) ;
1512+ let l = pk. decrypt ( & ct, & mut pt, rng) ;
1513+ assert_eq ! ( l. unwrap( ) , LEN ) ;
1514+ }
1515+ }
14731516}
0 commit comments