• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::super::{Bounds, N, PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN};
2 use crate::{
3     arithmetic::{bigint, montgomery::Unencoded},
4     bits, cpu, error,
5     limb::LIMB_BYTES,
6 };
7 use alloc::boxed::Box;
8 
9 /// An RSA Public Key.
10 #[derive(Clone, Debug)]
11 pub struct Key {
12     n: PublicModulus,
13     e: PublicExponent,
14 }
15 
16 impl Key {
17     /// Constructs a `Key` from its components.
try_from_components<B>( components: &super::Components<B>, bounds: &dyn Bounds, ) -> Result<Self, error::KeyRejected> where B: AsRef<[u8]> + core::fmt::Debug,18     pub fn try_from_components<B>(
19         components: &super::Components<B>,
20         bounds: &dyn Bounds,
21     ) -> Result<Self, error::KeyRejected>
22     where
23         B: AsRef<[u8]> + core::fmt::Debug,
24     {
25         Self::from_modulus_and_exponent(components.n.as_ref(), components.e.as_ref(), bounds)
26     }
27 
28     /// Constructs the key from the public modulus `n` and the public exponent `e`,
29     /// verifying that they meet the bounds `bounds`.
from_modulus_and_exponent( n: &[u8], e: &[u8], bounds: &dyn Bounds, ) -> Result<Self, error::KeyRejected>30     pub fn from_modulus_and_exponent(
31         n: &[u8],
32         e: &[u8],
33         bounds: &dyn Bounds,
34     ) -> Result<Self, error::KeyRejected> {
35         let _ = cpu::features();
36         let n = untrusted::Input::from(n);
37         let e = untrusted::Input::from(e);
38 
39         // This is an incomplete implementation of NIST SP800-56Br1 Section
40         // 6.4.2.2, "Partial Public-Key Validation for RSA." That spec defers
41         // to NIST SP800-89 Section 5.3.3, "(Explicit) Partial Public Key
42         // Validation for RSA," "with the caveat that the length of the modulus
43         // shall be a length that is specified in this Recommendation." In
44         // SP800-89, two different sets of steps are given, one set numbered,
45         // and one set lettered. TODO: Document this in the end-user
46         // documentation for RSA keys.
47 
48         let n = PublicModulus::new(n, bounds.n_min_bits(), bounds.n_max_bits())?;
49 
50         // If `n` is less than `e` then somebody has probably accidentally swapped
51         // them. The largest acceptable `e` is smaller than the smallest acceptable
52         // `n`, so no additional checks need to be done.
53         let e = PublicExponent::new(e, bounds.e_min_value())?;
54 
55         // XXX: Steps 4 & 5 / Steps d, e, & f are not implemented. This is also the
56         // case in most other commonly-used crypto libraries.
57 
58         Ok(Self { n, e })
59     }
60 
61     /// The public modulus.
62     #[inline]
n(&self) -> &PublicModulus63     pub fn n(&self) -> &PublicModulus {
64         &self.n
65     }
66 
67     /// The public exponent.
68     #[inline]
e(&self) -> &PublicExponent69     pub fn e(&self) -> &PublicExponent {
70         &self.e
71     }
72 
exponentiate<'in_out>( &self, input: untrusted::Input, out_buffer: &'in_out mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN], ) -> Result<&'in_out [u8], error::Unspecified>73     pub(in crate::rsa) fn exponentiate<'in_out>(
74         &self,
75         input: untrusted::Input,
76         out_buffer: &'in_out mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN], // TODO: clean this up
77     ) -> Result<&'in_out [u8], error::Unspecified> {
78         let n = &self.n.value;
79         let n_bits = self.n.bits;
80         let e = self.e.0;
81 
82         // The signature must be the same length as the modulus, in bytes.
83         if input.len() != self.n.len_bits().as_usize_bytes_rounded_up() {
84             return Err(error::Unspecified);
85         }
86 
87         // RFC 8017 Section 5.2.2: RSAVP1.
88 
89         // Step 1.
90         let s = bigint::Elem::from_be_bytes_padded(input, n)?;
91         if s.is_zero() {
92             return Err(error::Unspecified);
93         }
94 
95         // Step 2.
96         let m = bigint::elem_exp_vartime(s, e, n);
97         let m = m.into_unencoded(n);
98 
99         // Step 3.
100         Ok(fill_be_bytes_n(m, n_bits, out_buffer))
101     }
102 }
103 
104 /// Returns the big-endian representation of `elem` that is
105 /// the same length as the minimal-length big-endian representation of
106 /// the modulus `n`.
107 ///
108 /// `n_bits` must be the bit length of the public modulus `n`.
fill_be_bytes_n( elem: bigint::Elem<N, Unencoded>, n_bits: bits::BitLength, out: &mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN], ) -> &[u8]109 fn fill_be_bytes_n(
110     elem: bigint::Elem<N, Unencoded>,
111     n_bits: bits::BitLength,
112     out: &mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN],
113 ) -> &[u8] {
114     let n_bytes = n_bits.as_usize_bytes_rounded_up();
115     let n_bytes_padded = ((n_bytes + (LIMB_BYTES - 1)) / LIMB_BYTES) * LIMB_BYTES;
116     let out = &mut out[..n_bytes_padded];
117     elem.fill_be_bytes(out);
118     let (padding, out) = out.split_at(n_bytes_padded - n_bytes);
119     assert!(padding.iter().all(|&b| b == 0));
120     out
121 }
122 
123 #[derive(Clone)]
124 pub struct PublicModulus {
125     pub(in crate::rsa) value: bigint::Modulus<N>,
126     bits: bits::BitLength,
127 }
128 
129 impl core::fmt::Debug for PublicModulus {
fmt(&self, fmt: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error>130     fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {
131         self.value.fmt(fmt)
132     }
133 }
134 
135 impl PublicModulus {
new( n: untrusted::Input, min_bits: bits::BitLength, max_bits: bits::BitLength, ) -> Result<Self, error::KeyRejected>136     fn new(
137         n: untrusted::Input,
138         min_bits: bits::BitLength,
139         max_bits: bits::BitLength,
140     ) -> Result<Self, error::KeyRejected> {
141         // `pkcs1_encode` depends on this not being small. Otherwise,
142         // `pkcs1_encode` would generate padding that is invalid (too few 0xFF
143         // bytes) for very small keys.
144         const MIN_BITS: bits::BitLength = bits::BitLength::from_usize_bits(1024);
145 
146         // Step 3 / Step c for `n` (out of order).
147         let (value, bits) = bigint::Modulus::from_be_bytes_with_bit_length(n)?;
148 
149         // Step 1 / Step a. XXX: SP800-56Br1 and SP800-89 require the length of
150         // the public modulus to be exactly 2048 or 3072 bits, but we are more
151         // flexible to be compatible with other commonly-used crypto libraries.
152         assert!(min_bits >= MIN_BITS);
153         let bits_rounded_up =
154             bits::BitLength::from_usize_bytes(bits.as_usize_bytes_rounded_up())
155                 .map_err(|error::Unspecified| error::KeyRejected::unexpected_error())?;
156         if bits_rounded_up < min_bits {
157             return Err(error::KeyRejected::too_small());
158         }
159         if bits > max_bits {
160             return Err(error::KeyRejected::too_large());
161         }
162 
163         Ok(Self { value, bits })
164     }
165 
166     #[inline]
len_bits(&self) -> bits::BitLength167     pub(crate) fn len_bits(&self) -> bits::BitLength {
168         self.bits
169     }
170 
171     /// The length of the modulus in bytes.
172     #[inline]
len(&self) -> usize173     pub fn len(&self) -> usize {
174         self.bits.as_usize_bytes_rounded_up()
175     }
176 
177     /// Returns the big-endian serislization of the modulus's value.
178     #[inline]
to_be_bytes(&self) -> Box<[u8]>179     pub fn to_be_bytes(&self) -> Box<[u8]> {
180         self.value.to_be_bytes()
181     }
182 }
183 
184 #[derive(Clone)]
185 pub struct PublicExponent(pub(in crate::rsa) bigint::PublicExponent);
186 
187 impl PublicExponent {
new(e: untrusted::Input, e_min_value: u64) -> Result<Self, error::KeyRejected>188     fn new(e: untrusted::Input, e_min_value: u64) -> Result<Self, error::KeyRejected> {
189         // XXX: FIPS 186-4 seems to indicate that the minimum
190         // exponent value is 2**16 + 1, but it isn't clear if this is just for
191         // signing or also for verification. We support exponents of 3 and larger
192         // for compatibility with other commonly-used crypto libraries.
193 
194         // Step 2 / Step b.
195         // Step 3 / Step c for `e`.
196         Ok(Self(bigint::PublicExponent::from_be_bytes(e, e_min_value)?))
197     }
198 
199     #[inline]
to_be_bytes(&self) -> Box<[u8]>200     pub fn to_be_bytes(&self) -> Box<[u8]> {
201         self.0.to_be_bytes()
202     }
203 }
204 
205 impl core::fmt::Debug for PublicExponent {
fmt(&self, fmt: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error>206     fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {
207         self.0.fmt(fmt)
208     }
209 }
210