Skip to content

Commit 51429f1

Browse files
authored
Merge pull request fortanix#339 from fortanix/francisco/fips-rsadp-bounds
Add ciphertext check for RSADP
2 parents cc49440 + 0a96396 commit 51429f1

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

mbedtls/src/pk/mod.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::hash::Type as MdType;
1717
use crate::private::UnsafeFrom;
1818
use crate::rng::Random;
1919
use core::convert::TryInto;
20+
use core::ops::Sub;
2021
use core::ptr;
2122

2223
use 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

Comments
 (0)