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