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