1 use crate::{arithmetic::bigint, bits, cpu, error, rsa::N}; 2 use core::ops::RangeInclusive; 3 4 /// The modulus (n) of an RSA public key. 5 #[derive(Clone)] 6 pub struct PublicModulus { 7 value: bigint::Modulus<N>, 8 bits: bits::BitLength, 9 } 10 11 /* 12 impl core::fmt::Debug for PublicModulus { 13 fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> { 14 self.value.fmt(fmt) 15 } 16 }*/ 17 18 impl PublicModulus { from_be_bytes( n: untrusted::Input, allowed_bit_lengths: RangeInclusive<bits::BitLength>, cpu_features: cpu::Features, ) -> Result<Self, error::KeyRejected>19 pub(super) fn from_be_bytes( 20 n: untrusted::Input, 21 allowed_bit_lengths: RangeInclusive<bits::BitLength>, 22 cpu_features: cpu::Features, 23 ) -> Result<Self, error::KeyRejected> { 24 // See `PublicKey::from_modulus_and_exponent` for background on the step 25 // numbering. 26 27 let min_bits = *allowed_bit_lengths.start(); 28 let max_bits = *allowed_bit_lengths.end(); 29 30 // `pkcs1_encode` depends on this not being small. Otherwise, 31 // `pkcs1_encode` would generate padding that is invalid (too few 0xFF 32 // bytes) for very small keys. 33 const MIN_BITS: bits::BitLength = bits::BitLength::from_usize_bits(1024); 34 35 // Step 3 / Step c for `n` (out of order). 36 let (value, bits) = bigint::Modulus::from_be_bytes_with_bit_length(n, cpu_features)?; 37 38 // Step 1 / Step a. XXX: SP800-56Br1 and SP800-89 require the length of 39 // the public modulus to be exactly 2048 or 3072 bits, but we are more 40 // flexible to be compatible with other commonly-used crypto libraries. 41 assert!(min_bits >= MIN_BITS); 42 let bits_rounded_up = 43 bits::BitLength::from_usize_bytes(bits.as_usize_bytes_rounded_up()).unwrap(); // TODO: safe? 44 if bits_rounded_up < min_bits { 45 return Err(error::KeyRejected::too_small()); 46 } 47 if bits > max_bits { 48 return Err(error::KeyRejected::too_large()); 49 } 50 51 Ok(Self { value, bits }) 52 } 53 54 /// The big-endian encoding of the modulus. 55 /// 56 /// There are no leading zeros. be_bytes(&self) -> impl ExactSizeIterator<Item = u8> + Clone + '_57 pub fn be_bytes(&self) -> impl ExactSizeIterator<Item = u8> + Clone + '_ { 58 self.value.be_bytes() 59 } 60 61 /// The length of the modulus in bits. len_bits(&self) -> bits::BitLength62 pub fn len_bits(&self) -> bits::BitLength { 63 self.bits 64 } 65 value(&self) -> &bigint::Modulus<N>66 pub(super) fn value(&self) -> &bigint::Modulus<N> { 67 &self.value 68 } 69 } 70