ring/rsa/
public_key.rs

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 AUTHOR DISCLAIMS ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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
15use super::{PublicExponent, PublicModulus, N, PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN};
16use crate::{
17    arithmetic::bigint,
18    bits, cpu, error,
19    io::{self, der, der_writer},
20    limb::LIMB_BYTES,
21};
22use alloc::boxed::Box;
23use core::num::NonZeroU64;
24
25/// An RSA Public Key.
26#[derive(Clone)]
27pub struct PublicKey {
28    inner: Inner,
29    serialized: Box<[u8]>,
30}
31
32derive_debug_self_as_ref_hex_bytes!(PublicKey);
33
34impl PublicKey {
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 inner = Inner::from_modulus_and_exponent(
44            n,
45            e,
46            n_min_bits,
47            n_max_bits,
48            e_min_value,
49            cpu_features,
50        )?;
51
52        let n_bytes = n;
53        let e_bytes = e;
54
55        // TODO: Remove this re-parsing, and stop allocating this here.
56        // Instead we should serialize on demand without allocation, from
57        // `Modulus::be_bytes()` and `Exponent::be_bytes()`. Once this is
58        // fixed, merge `Inner` back into `PublicKey`.
59        let n_bytes = io::Positive::from_be_bytes(n_bytes)
60            .map_err(|_: error::Unspecified| error::KeyRejected::unexpected_error())?;
61        let e_bytes = io::Positive::from_be_bytes(e_bytes)
62            .map_err(|_: error::Unspecified| error::KeyRejected::unexpected_error())?;
63        let serialized = der_writer::write_all(der::Tag::Sequence, &|output| {
64            der_writer::write_positive_integer(output, &n_bytes)?;
65            der_writer::write_positive_integer(output, &e_bytes)
66        })
67        .map_err(|_: io::TooLongError| error::KeyRejected::unexpected_error())?;
68
69        Ok(Self { inner, serialized })
70    }
71
72    /// The length, in bytes, of the public modulus.
73    ///
74    /// The modulus length is rounded up to a whole number of bytes if its
75    /// bit length isn't a multiple of 8.
76    pub fn modulus_len(&self) -> usize {
77        self.inner.n().len_bits().as_usize_bytes_rounded_up()
78    }
79
80    pub(super) fn inner(&self) -> &Inner {
81        &self.inner
82    }
83}
84
85/// `PublicKey` but without any superfluous allocations, optimized for one-shot
86/// RSA signature verification.
87#[derive(Clone)]
88pub(crate) struct Inner {
89    n: PublicModulus,
90    e: PublicExponent,
91}
92
93impl Inner {
94    pub(super) fn from_modulus_and_exponent(
95        n: untrusted::Input,
96        e: untrusted::Input,
97        n_min_bits: bits::BitLength,
98        n_max_bits: bits::BitLength,
99        e_min_value: PublicExponent,
100        cpu_features: cpu::Features,
101    ) -> Result<Self, error::KeyRejected> {
102        // This is an incomplete implementation of NIST SP800-56Br1 Section
103        // 6.4.2.2, "Partial Public-Key Validation for RSA." That spec defers
104        // to NIST SP800-89 Section 5.3.3, "(Explicit) Partial Public Key
105        // Validation for RSA," "with the caveat that the length of the modulus
106        // shall be a length that is specified in this Recommendation." In
107        // SP800-89, two different sets of steps are given, one set numbered,
108        // and one set lettered. TODO: Document this in the end-user
109        // documentation for RSA keys.
110
111        let n = PublicModulus::from_be_bytes(n, n_min_bits..=n_max_bits, cpu_features)?;
112
113        let e = PublicExponent::from_be_bytes(e, e_min_value)?;
114
115        // If `n` is less than `e` then somebody has probably accidentally swapped
116        // them. The largest acceptable `e` is smaller than the smallest acceptable
117        // `n`, so no additional checks need to be done.
118
119        // XXX: Steps 4 & 5 / Steps d, e, & f are not implemented. This is also the
120        // case in most other commonly-used crypto libraries.
121
122        Ok(Self { n, e })
123    }
124
125    /// The public modulus.
126    #[inline]
127    pub(super) fn n(&self) -> &PublicModulus {
128        &self.n
129    }
130
131    /// The public exponent.
132    #[inline]
133    pub(super) fn e(&self) -> PublicExponent {
134        self.e
135    }
136
137    /// Calculates base**e (mod n), filling the first part of `out_buffer` with
138    /// the result.
139    ///
140    /// This is constant-time with respect to the value in `base` (only).
141    ///
142    /// The result will be a slice of the encoded bytes of the result within
143    /// `out_buffer`, if successful.
144    pub(super) fn exponentiate<'out>(
145        &self,
146        base: untrusted::Input,
147        out_buffer: &'out mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN],
148        cpu_features: cpu::Features,
149    ) -> Result<&'out [u8], error::Unspecified> {
150        let n = &self.n.value(cpu_features);
151
152        // The encoded value of the base must be the same length as the modulus,
153        // in bytes.
154        if base.len() != self.n.len_bits().as_usize_bytes_rounded_up() {
155            return Err(error::Unspecified);
156        }
157
158        // RFC 8017 Section 5.2.2: RSAVP1.
159
160        // Step 1.
161        let s = bigint::Elem::from_be_bytes_padded(base, n)?;
162        if s.is_zero() {
163            return Err(error::Unspecified);
164        }
165
166        // Step 2.
167        let m = n.alloc_zero();
168        let m = self.exponentiate_elem(m, &s, cpu_features);
169
170        // Step 3.
171        Ok(fill_be_bytes_n(m, self.n.len_bits(), out_buffer))
172    }
173
174    /// Calculates base**e (mod n).
175    ///
176    /// This is constant-time with respect to `base` only.
177    pub(super) fn exponentiate_elem(
178        &self,
179        out: bigint::Storage<N>,
180        base: &bigint::Elem<N>,
181        cpu_features: cpu::Features,
182    ) -> bigint::Elem<N> {
183        // The exponent was already checked to be at least 3.
184        let exponent_without_low_bit = NonZeroU64::try_from(self.e.value().get() & !1).unwrap();
185        // The exponent was already checked to be odd.
186        debug_assert_ne!(exponent_without_low_bit, self.e.value());
187
188        let n = &self.n.value(cpu_features);
189
190        let tmp = n.alloc_zero();
191        let base_r = bigint::elem_mul_into(tmp, self.n.oneRR(), base, n);
192
193        // During RSA public key operations the exponent is almost always either
194        // 65537 (0b10000000000000001) or 3 (0b11), both of which have a Hamming
195        // weight of 2. The maximum bit length and maximum Hamming weight of the
196        // exponent is bounded by the value of `PublicExponent::MAX`.
197        let acc = bigint::elem_exp_vartime(out, base_r, exponent_without_low_bit, n);
198
199        // Now do the multiplication for the low bit and convert out of the Montgomery domain.
200        bigint::elem_mul(base, acc, n)
201    }
202}
203
204// XXX: Refactor `signature::KeyPair` to get rid of this.
205impl AsRef<[u8]> for PublicKey {
206    fn as_ref(&self) -> &[u8] {
207        &self.serialized
208    }
209}
210
211/// Returns the big-endian representation of `elem` that is
212/// the same length as the minimal-length big-endian representation of
213/// the modulus `n`.
214///
215/// `n_bits` must be the bit length of the public modulus `n`.
216fn fill_be_bytes_n(
217    elem: bigint::Elem<N>,
218    n_bits: bits::BitLength,
219    out: &mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN],
220) -> &[u8] {
221    let n_bytes = n_bits.as_usize_bytes_rounded_up();
222    let n_bytes_padded = ((n_bytes + (LIMB_BYTES - 1)) / LIMB_BYTES) * LIMB_BYTES;
223    let out = &mut out[..n_bytes_padded];
224    elem.fill_be_bytes(out);
225    let (padding, out) = out.split_at(n_bytes_padded - n_bytes);
226    assert!(padding.iter().all(|&b| b == 0));
227    out
228}