ring/rsa/
verification.rs

1// Copyright 2015-2016 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//! Verification of RSA signatures.
16
17use super::{parse_public_key, RsaParameters, N, PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN};
18use crate::{
19    arithmetic::{bigint, montgomery::Unencoded},
20    bits, cpu, digest, error,
21    limb::LIMB_BYTES,
22    sealed, signature,
23};
24
25#[derive(Debug)]
26pub struct Key {
27    pub n: bigint::Modulus<N>,
28    pub e: bigint::PublicExponent,
29    pub n_bits: bits::BitLength,
30}
31
32impl Key {
33    pub fn from_modulus_and_exponent(
34        n: untrusted::Input,
35        e: untrusted::Input,
36        n_min_bits: bits::BitLength,
37        n_max_bits: bits::BitLength,
38        e_min_value: u64,
39    ) -> Result<Self, error::KeyRejected> {
40        // This is an incomplete implementation of NIST SP800-56Br1 Section
41        // 6.4.2.2, "Partial Public-Key Validation for RSA." That spec defers
42        // to NIST SP800-89 Section 5.3.3, "(Explicit) Partial Public Key
43        // Validation for RSA," "with the caveat that the length of the modulus
44        // shall be a length that is specified in this Recommendation." In
45        // SP800-89, two different sets of steps are given, one set numbered,
46        // and one set lettered. TODO: Document this in the end-user
47        // documentation for RSA keys.
48
49        // Step 3 / Step c for `n` (out of order).
50        let (n, n_bits) = bigint::Modulus::from_be_bytes_with_bit_length(n)?;
51
52        // `pkcs1_encode` depends on this not being small. Otherwise,
53        // `pkcs1_encode` would generate padding that is invalid (too few 0xFF
54        // bytes) for very small keys.
55        const N_MIN_BITS: bits::BitLength = bits::BitLength::from_usize_bits(1024);
56
57        // Step 1 / Step a. XXX: SP800-56Br1 and SP800-89 require the length of
58        // the public modulus to be exactly 2048 or 3072 bits, but we are more
59        // flexible to be compatible with other commonly-used crypto libraries.
60        assert!(n_min_bits >= N_MIN_BITS);
61        let n_bits_rounded_up =
62            bits::BitLength::from_usize_bytes(n_bits.as_usize_bytes_rounded_up())
63                .map_err(|error::Unspecified| error::KeyRejected::unexpected_error())?;
64        if n_bits_rounded_up < n_min_bits {
65            return Err(error::KeyRejected::too_small());
66        }
67        if n_bits > n_max_bits {
68            return Err(error::KeyRejected::too_large());
69        }
70
71        // Step 2 / Step b.
72        // Step 3 / Step c for `e`.
73        let e = bigint::PublicExponent::from_be_bytes(e, e_min_value)?;
74
75        // If `n` is less than `e` then somebody has probably accidentally swapped
76        // them. The largest acceptable `e` is smaller than the smallest acceptable
77        // `n`, so no additional checks need to be done.
78
79        // XXX: Steps 4 & 5 / Steps d, e, & f are not implemented. This is also the
80        // case in most other commonly-used crypto libraries.
81
82        Ok(Self { n, e, n_bits })
83    }
84}
85
86impl signature::VerificationAlgorithm for RsaParameters {
87    fn verify(
88        &self,
89        public_key: untrusted::Input,
90        msg: untrusted::Input,
91        signature: untrusted::Input,
92    ) -> Result<(), error::Unspecified> {
93        let (n, e) = parse_public_key(public_key)?;
94        verify_rsa_(
95            self,
96            (
97                n.big_endian_without_leading_zero_as_input(),
98                e.big_endian_without_leading_zero_as_input(),
99            ),
100            msg,
101            signature,
102        )
103    }
104}
105
106impl sealed::Sealed for RsaParameters {}
107
108macro_rules! rsa_params {
109    ( $VERIFY_ALGORITHM:ident, $min_bits:expr, $PADDING_ALGORITHM:expr,
110      $doc_str:expr ) => {
111        #[doc=$doc_str]
112        ///
113        /// Only available in `alloc` mode.
114        pub static $VERIFY_ALGORITHM: RsaParameters = RsaParameters {
115            padding_alg: $PADDING_ALGORITHM,
116            min_bits: bits::BitLength::from_usize_bits($min_bits),
117        };
118    };
119}
120
121rsa_params!(
122    RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
123    1024,
124    &super::padding::RSA_PKCS1_SHA1_FOR_LEGACY_USE_ONLY,
125    "Verification of signatures using RSA keys of 1024-8192 bits,
126             PKCS#1.5 padding, and SHA-1.\n\nSee \"`RSA_PKCS1_*` Details\" in
127             `ring::signature`'s module-level documentation for more details."
128);
129rsa_params!(
130    RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY,
131    2048,
132    &super::padding::RSA_PKCS1_SHA1_FOR_LEGACY_USE_ONLY,
133    "Verification of signatures using RSA keys of 2048-8192 bits,
134             PKCS#1.5 padding, and SHA-1.\n\nSee \"`RSA_PKCS1_*` Details\" in
135             `ring::signature`'s module-level documentation for more details."
136);
137rsa_params!(
138    RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY,
139    1024,
140    &super::RSA_PKCS1_SHA256,
141    "Verification of signatures using RSA keys of 1024-8192 bits,
142             PKCS#1.5 padding, and SHA-256.\n\nSee \"`RSA_PKCS1_*` Details\" in
143             `ring::signature`'s module-level documentation for more details."
144);
145rsa_params!(
146    RSA_PKCS1_2048_8192_SHA256,
147    2048,
148    &super::RSA_PKCS1_SHA256,
149    "Verification of signatures using RSA keys of 2048-8192 bits,
150             PKCS#1.5 padding, and SHA-256.\n\nSee \"`RSA_PKCS1_*` Details\" in
151             `ring::signature`'s module-level documentation for more details."
152);
153rsa_params!(
154    RSA_PKCS1_2048_8192_SHA384,
155    2048,
156    &super::RSA_PKCS1_SHA384,
157    "Verification of signatures using RSA keys of 2048-8192 bits,
158             PKCS#1.5 padding, and SHA-384.\n\nSee \"`RSA_PKCS1_*` Details\" in
159             `ring::signature`'s module-level documentation for more details."
160);
161rsa_params!(
162    RSA_PKCS1_2048_8192_SHA512,
163    2048,
164    &super::RSA_PKCS1_SHA512,
165    "Verification of signatures using RSA keys of 2048-8192 bits,
166             PKCS#1.5 padding, and SHA-512.\n\nSee \"`RSA_PKCS1_*` Details\" in
167             `ring::signature`'s module-level documentation for more details."
168);
169rsa_params!(
170    RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY,
171    1024,
172    &super::RSA_PKCS1_SHA512,
173    "Verification of signatures using RSA keys of 1024-8192 bits,
174             PKCS#1.5 padding, and SHA-512.\n\nSee \"`RSA_PKCS1_*` Details\" in
175             `ring::signature`'s module-level documentation for more details."
176);
177rsa_params!(
178    RSA_PKCS1_3072_8192_SHA384,
179    3072,
180    &super::RSA_PKCS1_SHA384,
181    "Verification of signatures using RSA keys of 3072-8192 bits,
182             PKCS#1.5 padding, and SHA-384.\n\nSee \"`RSA_PKCS1_*` Details\" in
183             `ring::signature`'s module-level documentation for more details."
184);
185
186rsa_params!(
187    RSA_PSS_2048_8192_SHA256,
188    2048,
189    &super::RSA_PSS_SHA256,
190    "Verification of signatures using RSA keys of 2048-8192 bits,
191             PSS padding, and SHA-256.\n\nSee \"`RSA_PSS_*` Details\" in
192             `ring::signature`'s module-level documentation for more details."
193);
194rsa_params!(
195    RSA_PSS_2048_8192_SHA384,
196    2048,
197    &super::RSA_PSS_SHA384,
198    "Verification of signatures using RSA keys of 2048-8192 bits,
199             PSS padding, and SHA-384.\n\nSee \"`RSA_PSS_*` Details\" in
200             `ring::signature`'s module-level documentation for more details."
201);
202rsa_params!(
203    RSA_PSS_2048_8192_SHA512,
204    2048,
205    &super::RSA_PSS_SHA512,
206    "Verification of signatures using RSA keys of 2048-8192 bits,
207             PSS padding, and SHA-512.\n\nSee \"`RSA_PSS_*` Details\" in
208             `ring::signature`'s module-level documentation for more details."
209);
210
211/// Low-level API for the verification of RSA signatures.
212///
213/// When the public key is in DER-encoded PKCS#1 ASN.1 format, it is
214/// recommended to use `ring::signature::verify()` with
215/// `ring::signature::RSA_PKCS1_*`, because `ring::signature::verify()`
216/// will handle the parsing in that case. Otherwise, this function can be used
217/// to pass in the raw bytes for the public key components as
218/// `untrusted::Input` arguments.
219//
220// There are a small number of tests that test this directly, but the
221// test coverage for this function mostly depends on the test coverage for the
222// `signature::VerificationAlgorithm` implementation for `RsaParameters`. If we
223// change that, test coverage for `verify_rsa()` will need to be reconsidered.
224// (The NIST test vectors were originally in a form that was optimized for
225// testing `verify_rsa` directly, but the testing work for RSA PKCS#1
226// verification was done during the implementation of
227// `signature::VerificationAlgorithm`, before `verify_rsa` was factored out).
228#[derive(Debug)]
229pub struct RsaPublicKeyComponents<B: AsRef<[u8]> + core::fmt::Debug> {
230    /// The public modulus, encoded in big-endian bytes without leading zeros.
231    pub n: B,
232
233    /// The public exponent, encoded in big-endian bytes without leading zeros.
234    pub e: B,
235}
236
237impl<B: Copy> Copy for RsaPublicKeyComponents<B> where B: AsRef<[u8]> + core::fmt::Debug {}
238
239impl<B: Clone> Clone for RsaPublicKeyComponents<B>
240where
241    B: AsRef<[u8]> + core::fmt::Debug,
242{
243    fn clone(&self) -> Self {
244        Self {
245            n: self.n.clone(),
246            e: self.e.clone(),
247        }
248    }
249}
250
251impl<B> RsaPublicKeyComponents<B>
252where
253    B: AsRef<[u8]> + core::fmt::Debug,
254{
255    /// Verifies that `signature` is a valid signature of `message` using `self`
256    /// as the public key. `params` determine what algorithm parameters
257    /// (padding, digest algorithm, key length range, etc.) are used in the
258    /// verification.
259    pub fn verify(
260        &self,
261        params: &RsaParameters,
262        message: &[u8],
263        signature: &[u8],
264    ) -> Result<(), error::Unspecified> {
265        let _ = cpu::features();
266        verify_rsa_(
267            params,
268            (
269                untrusted::Input::from(self.n.as_ref()),
270                untrusted::Input::from(self.e.as_ref()),
271            ),
272            untrusted::Input::from(message),
273            untrusted::Input::from(signature),
274        )
275    }
276}
277
278pub(crate) fn verify_rsa_(
279    params: &RsaParameters,
280    (n, e): (untrusted::Input, untrusted::Input),
281    msg: untrusted::Input,
282    signature: untrusted::Input,
283) -> Result<(), error::Unspecified> {
284    let max_bits = bits::BitLength::from_usize_bytes(PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN)?;
285
286    // XXX: FIPS 186-4 seems to indicate that the minimum
287    // exponent value is 2**16 + 1, but it isn't clear if this is just for
288    // signing or also for verification. We support exponents of 3 and larger
289    // for compatibility with other commonly-used crypto libraries.
290    let Key { n, e, n_bits } = Key::from_modulus_and_exponent(n, e, params.min_bits, max_bits, 3)?;
291
292    // The signature must be the same length as the modulus, in bytes.
293    if signature.len() != n_bits.as_usize_bytes_rounded_up() {
294        return Err(error::Unspecified);
295    }
296
297    // RFC 8017 Section 5.2.2: RSAVP1.
298
299    // Step 1.
300    let s = bigint::Elem::from_be_bytes_padded(signature, &n)?;
301    if s.is_zero() {
302        return Err(error::Unspecified);
303    }
304
305    // Step 2.
306    let m = bigint::elem_exp_vartime(s, e, &n);
307    let m = m.into_unencoded(&n);
308
309    // Step 3.
310    let mut decoded = [0u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN];
311    let decoded = fill_be_bytes_n(m, n_bits, &mut decoded);
312
313    // Verify the padded message is correct.
314    let m_hash = digest::digest(params.padding_alg.digest_alg(), msg.as_slice_less_safe());
315    untrusted::Input::from(decoded).read_all(error::Unspecified, |m| {
316        params.padding_alg.verify(&m_hash, m, n_bits)
317    })
318}
319
320/// Returns the big-endian representation of `elem` that is
321/// the same length as the minimal-length big-endian representation of
322/// the modulus `n`.
323///
324/// `n_bits` must be the bit length of the public modulus `n`.
325fn fill_be_bytes_n(
326    elem: bigint::Elem<N, Unencoded>,
327    n_bits: bits::BitLength,
328    out: &mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN],
329) -> &[u8] {
330    let n_bytes = n_bits.as_usize_bytes_rounded_up();
331    let n_bytes_padded = ((n_bytes + (LIMB_BYTES - 1)) / LIMB_BYTES) * LIMB_BYTES;
332    let out = &mut out[..n_bytes_padded];
333    elem.fill_be_bytes(out);
334    let (padding, out) = out.split_at(n_bytes_padded - n_bytes);
335    assert!(padding.iter().all(|&b| b == 0));
336    out
337}