1 // Copyright 2015-2021 Brian Smith.
2 //
3 // Permission to use, copy, modify, and/or distribute this software for any
4 // purpose with or without fee is hereby granted, provided that the above
5 // copyright notice and this permission notice appear in all copies.
6 //
7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
10 // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 
15 use super::{PublicExponent, PublicModulus, N, PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN};
16 use crate::{
17     arithmetic::bigint,
18     bits, cpu, error,
19     io::{self, der, der_writer},
20     limb::LIMB_BYTES,
21 };
22 use alloc::boxed::Box;
23 
24 /// An RSA Public Key.
25 #[derive(Clone)]
26 pub struct PublicKey {
27     n: PublicModulus,
28     e: PublicExponent,
29     serialized: Box<[u8]>,
30 }
31 
32 derive_debug_self_as_ref_hex_bytes!(PublicKey);
33 
34 impl PublicKey {
from_modulus_and_exponent( n: untrusted::Input, e: untrusted::Input, n_min_bits: bits::BitLength, n_max_bits: bits::BitLength, e_min_value: PublicExponent, cpu_features: cpu::Features, ) -> Result<Self, error::KeyRejected>35     pub(super) fn from_modulus_and_exponent(
36         n: untrusted::Input,
37         e: untrusted::Input,
38         n_min_bits: bits::BitLength,
39         n_max_bits: bits::BitLength,
40         e_min_value: PublicExponent,
41         cpu_features: cpu::Features,
42     ) -> Result<Self, error::KeyRejected> {
43         let n_bytes = n;
44         let e_bytes = e;
45 
46         // This is an incomplete implementation of NIST SP800-56Br1 Section
47         // 6.4.2.2, "Partial Public-Key Validation for RSA." That spec defers
48         // to NIST SP800-89 Section 5.3.3, "(Explicit) Partial Public Key
49         // Validation for RSA," "with the caveat that the length of the modulus
50         // shall be a length that is specified in this Recommendation." In
51         // SP800-89, two different sets of steps are given, one set numbered,
52         // and one set lettered. TODO: Document this in the end-user
53         // documentation for RSA keys.
54 
55         let n = PublicModulus::from_be_bytes(n, n_min_bits..=n_max_bits, cpu_features)?;
56 
57         let e = PublicExponent::from_be_bytes(e, e_min_value)?;
58 
59         // If `n` is less than `e` then somebody has probably accidentally swapped
60         // them. The largest acceptable `e` is smaller than the smallest acceptable
61         // `n`, so no additional checks need to be done.
62 
63         // XXX: Steps 4 & 5 / Steps d, e, & f are not implemented. This is also the
64         // case in most other commonly-used crypto libraries.
65 
66         // TODO: Remove this re-parsing, and stop allocating this here.
67         // Instead we should serialize on demand without allocation, from
68         // `Modulus::be_bytes()` and `Exponent::be_bytes()`.
69         let n_bytes = io::Positive::from_be_bytes(n_bytes)
70             .map_err(|_: error::Unspecified| error::KeyRejected::unexpected_error())?;
71         let e_bytes = io::Positive::from_be_bytes(e_bytes)
72             .map_err(|_: error::Unspecified| error::KeyRejected::unexpected_error())?;
73         let serialized = der_writer::write_all(der::Tag::Sequence, &|output| {
74             der_writer::write_positive_integer(output, &n_bytes);
75             der_writer::write_positive_integer(output, &e_bytes);
76         });
77 
78         Ok(Self { n, e, serialized })
79     }
80 
81     /// The length, in bytes, of the public modulus.
82     ///
83     /// The modulus length is rounded up to a whole number of bytes if its
84     /// bit length isn't a multiple of 8.
modulus_len(&self) -> usize85     pub fn modulus_len(&self) -> usize {
86         self.n().len_bits().as_usize_bytes_rounded_up()
87     }
88 
89     /// The public modulus.
90     #[inline]
n(&self) -> &PublicModulus91     pub(super) fn n(&self) -> &PublicModulus {
92         &self.n
93     }
94 
95     /// The public exponent.
96     #[inline]
e(&self) -> PublicExponent97     pub(super) fn e(&self) -> PublicExponent {
98         self.e
99     }
100 
101     /// Calculates base**e (mod n), filling the first part of `out_buffer` with
102     /// the result.
103     ///
104     /// This is constant-time with respect to the value in `base` (only).
105     ///
106     /// The result will be a slice of the encoded bytes of the result within
107     /// `out_buffer`, if successful.
exponentiate<'out>( &self, base: untrusted::Input, out_buffer: &'out mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN], ) -> Result<&'out [u8], error::Unspecified>108     pub(super) fn exponentiate<'out>(
109         &self,
110         base: untrusted::Input,
111         out_buffer: &'out mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN],
112     ) -> Result<&'out [u8], error::Unspecified> {
113         let n = &self.n.value();
114 
115         // The encoded value of the base must be the same length as the modulus,
116         // in bytes.
117         if base.len() != self.n.len_bits().as_usize_bytes_rounded_up() {
118             return Err(error::Unspecified);
119         }
120 
121         // RFC 8017 Section 5.2.2: RSAVP1.
122 
123         // Step 1.
124         let s = bigint::Elem::from_be_bytes_padded(base, n)?;
125         if s.is_zero() {
126             return Err(error::Unspecified);
127         }
128 
129         // Step 2.
130         let m = self.exponentiate_elem(s);
131 
132         // Step 3.
133         Ok(fill_be_bytes_n(m, self.n.len_bits(), out_buffer))
134     }
135 
136     /// Calculates base**e (mod n).
137     ///
138     /// This is constant-time with respect to `base` only.
exponentiate_elem(&self, base: bigint::Elem<N>) -> bigint::Elem<N>139     pub(super) fn exponentiate_elem(&self, base: bigint::Elem<N>) -> bigint::Elem<N> {
140         let n = self.n.value();
141 
142         let base = bigint::elem_mul(n.oneRR().as_ref(), base, n);
143         // During RSA public key operations the exponent is almost always either
144         // 65537 (0b10000000000000001) or 3 (0b11), both of which have a Hamming
145         // weight of 2. The maximum bit length and maximum Hamming weight of the
146         // exponent is bounded by the value of `PublicExponent::MAX`.
147         bigint::elem_exp_vartime(base, self.e.value(), &n.as_partial()).into_unencoded(n)
148     }
149 }
150 
151 // XXX: Refactor `signature::KeyPair` to get rid of this.
152 impl AsRef<[u8]> for PublicKey {
as_ref(&self) -> &[u8]153     fn as_ref(&self) -> &[u8] {
154         &self.serialized
155     }
156 }
157 
158 /// Returns the big-endian representation of `elem` that is
159 /// the same length as the minimal-length big-endian representation of
160 /// the modulus `n`.
161 ///
162 /// `n_bits` must be the bit length of the public modulus `n`.
fill_be_bytes_n( elem: bigint::Elem<N>, n_bits: bits::BitLength, out: &mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN], ) -> &[u8]163 fn fill_be_bytes_n(
164     elem: bigint::Elem<N>,
165     n_bits: bits::BitLength,
166     out: &mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN],
167 ) -> &[u8] {
168     let n_bytes = n_bits.as_usize_bytes_rounded_up();
169     let n_bytes_padded = ((n_bytes + (LIMB_BYTES - 1)) / LIMB_BYTES) * LIMB_BYTES;
170     let out = &mut out[..n_bytes_padded];
171     elem.fill_be_bytes(out);
172     let (padding, out) = out.split_at(n_bytes_padded - n_bytes);
173     assert!(padding.iter().all(|&b| b == 0));
174     out
175 }
176