// Copyright 2015-2016 Brian Smith. // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. //! Verification of RSA signatures. use super::{parse_public_key, RsaParameters, N, PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN}; use crate::{ arithmetic::{bigint, montgomery::Unencoded}, bits, cpu, digest, error, limb::LIMB_BYTES, sealed, signature, }; #[derive(Debug)] pub struct Key { pub n: bigint::Modulus, pub e: bigint::PublicExponent, pub n_bits: bits::BitLength, } impl Key { pub fn from_modulus_and_exponent( n: untrusted::Input, e: untrusted::Input, n_min_bits: bits::BitLength, n_max_bits: bits::BitLength, e_min_value: u64, ) -> Result { // This is an incomplete implementation of NIST SP800-56Br1 Section // 6.4.2.2, "Partial Public-Key Validation for RSA." That spec defers // to NIST SP800-89 Section 5.3.3, "(Explicit) Partial Public Key // Validation for RSA," "with the caveat that the length of the modulus // shall be a length that is specified in this Recommendation." In // SP800-89, two different sets of steps are given, one set numbered, // and one set lettered. TODO: Document this in the end-user // documentation for RSA keys. // Step 3 / Step c for `n` (out of order). let (n, n_bits) = bigint::Modulus::from_be_bytes_with_bit_length(n)?; // `pkcs1_encode` depends on this not being small. Otherwise, // `pkcs1_encode` would generate padding that is invalid (too few 0xFF // bytes) for very small keys. const N_MIN_BITS: bits::BitLength = bits::BitLength::from_usize_bits(1024); // Step 1 / Step a. XXX: SP800-56Br1 and SP800-89 require the length of // the public modulus to be exactly 2048 or 3072 bits, but we are more // flexible to be compatible with other commonly-used crypto libraries. assert!(n_min_bits >= N_MIN_BITS); let n_bits_rounded_up = bits::BitLength::from_usize_bytes(n_bits.as_usize_bytes_rounded_up()) .map_err(|error::Unspecified| error::KeyRejected::unexpected_error())?; if n_bits_rounded_up < n_min_bits { return Err(error::KeyRejected::too_small()); } if n_bits > n_max_bits { return Err(error::KeyRejected::too_large()); } // Step 2 / Step b. // Step 3 / Step c for `e`. let e = bigint::PublicExponent::from_be_bytes(e, e_min_value)?; // If `n` is less than `e` then somebody has probably accidentally swapped // them. The largest acceptable `e` is smaller than the smallest acceptable // `n`, so no additional checks need to be done. // XXX: Steps 4 & 5 / Steps d, e, & f are not implemented. This is also the // case in most other commonly-used crypto libraries. Ok(Self { n, e, n_bits }) } } impl signature::VerificationAlgorithm for RsaParameters { fn verify( &self, public_key: untrusted::Input, msg: untrusted::Input, signature: untrusted::Input, ) -> Result<(), error::Unspecified> { let (n, e) = parse_public_key(public_key)?; verify_rsa_( self, ( n.big_endian_without_leading_zero_as_input(), e.big_endian_without_leading_zero_as_input(), ), msg, signature, ) } } impl sealed::Sealed for RsaParameters {} macro_rules! rsa_params { ( $VERIFY_ALGORITHM:ident, $min_bits:expr, $PADDING_ALGORITHM:expr, $doc_str:expr ) => { #[doc=$doc_str] /// /// Only available in `alloc` mode. pub static $VERIFY_ALGORITHM: RsaParameters = RsaParameters { padding_alg: $PADDING_ALGORITHM, min_bits: bits::BitLength::from_usize_bits($min_bits), }; }; } rsa_params!( RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY, 1024, &super::padding::RSA_PKCS1_SHA1_FOR_LEGACY_USE_ONLY, "Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-1.\n\nSee \"`RSA_PKCS1_*` Details\" in `ring::signature`'s module-level documentation for more details." ); rsa_params!( RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY, 2048, &super::padding::RSA_PKCS1_SHA1_FOR_LEGACY_USE_ONLY, "Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-1.\n\nSee \"`RSA_PKCS1_*` Details\" in `ring::signature`'s module-level documentation for more details." ); rsa_params!( RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY, 1024, &super::RSA_PKCS1_SHA256, "Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-256.\n\nSee \"`RSA_PKCS1_*` Details\" in `ring::signature`'s module-level documentation for more details." ); rsa_params!( RSA_PKCS1_2048_8192_SHA256, 2048, &super::RSA_PKCS1_SHA256, "Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-256.\n\nSee \"`RSA_PKCS1_*` Details\" in `ring::signature`'s module-level documentation for more details." ); rsa_params!( RSA_PKCS1_2048_8192_SHA384, 2048, &super::RSA_PKCS1_SHA384, "Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-384.\n\nSee \"`RSA_PKCS1_*` Details\" in `ring::signature`'s module-level documentation for more details." ); rsa_params!( RSA_PKCS1_2048_8192_SHA512, 2048, &super::RSA_PKCS1_SHA512, "Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-512.\n\nSee \"`RSA_PKCS1_*` Details\" in `ring::signature`'s module-level documentation for more details." ); rsa_params!( RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY, 1024, &super::RSA_PKCS1_SHA512, "Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-512.\n\nSee \"`RSA_PKCS1_*` Details\" in `ring::signature`'s module-level documentation for more details." ); rsa_params!( RSA_PKCS1_3072_8192_SHA384, 3072, &super::RSA_PKCS1_SHA384, "Verification of signatures using RSA keys of 3072-8192 bits, PKCS#1.5 padding, and SHA-384.\n\nSee \"`RSA_PKCS1_*` Details\" in `ring::signature`'s module-level documentation for more details." ); rsa_params!( RSA_PSS_2048_8192_SHA256, 2048, &super::RSA_PSS_SHA256, "Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-256.\n\nSee \"`RSA_PSS_*` Details\" in `ring::signature`'s module-level documentation for more details." ); rsa_params!( RSA_PSS_2048_8192_SHA384, 2048, &super::RSA_PSS_SHA384, "Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-384.\n\nSee \"`RSA_PSS_*` Details\" in `ring::signature`'s module-level documentation for more details." ); rsa_params!( RSA_PSS_2048_8192_SHA512, 2048, &super::RSA_PSS_SHA512, "Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-512.\n\nSee \"`RSA_PSS_*` Details\" in `ring::signature`'s module-level documentation for more details." ); /// Low-level API for the verification of RSA signatures. /// /// When the public key is in DER-encoded PKCS#1 ASN.1 format, it is /// recommended to use `ring::signature::verify()` with /// `ring::signature::RSA_PKCS1_*`, because `ring::signature::verify()` /// will handle the parsing in that case. Otherwise, this function can be used /// to pass in the raw bytes for the public key components as /// `untrusted::Input` arguments. // // There are a small number of tests that test this directly, but the // test coverage for this function mostly depends on the test coverage for the // `signature::VerificationAlgorithm` implementation for `RsaParameters`. If we // change that, test coverage for `verify_rsa()` will need to be reconsidered. // (The NIST test vectors were originally in a form that was optimized for // testing `verify_rsa` directly, but the testing work for RSA PKCS#1 // verification was done during the implementation of // `signature::VerificationAlgorithm`, before `verify_rsa` was factored out). #[derive(Debug)] pub struct RsaPublicKeyComponents + core::fmt::Debug> { /// The public modulus, encoded in big-endian bytes without leading zeros. pub n: B, /// The public exponent, encoded in big-endian bytes without leading zeros. pub e: B, } impl Copy for RsaPublicKeyComponents where B: AsRef<[u8]> + core::fmt::Debug {} impl Clone for RsaPublicKeyComponents where B: AsRef<[u8]> + core::fmt::Debug, { fn clone(&self) -> Self { Self { n: self.n.clone(), e: self.e.clone(), } } } impl RsaPublicKeyComponents where B: AsRef<[u8]> + core::fmt::Debug, { /// Verifies that `signature` is a valid signature of `message` using `self` /// as the public key. `params` determine what algorithm parameters /// (padding, digest algorithm, key length range, etc.) are used in the /// verification. pub fn verify( &self, params: &RsaParameters, message: &[u8], signature: &[u8], ) -> Result<(), error::Unspecified> { let _ = cpu::features(); verify_rsa_( params, ( untrusted::Input::from(self.n.as_ref()), untrusted::Input::from(self.e.as_ref()), ), untrusted::Input::from(message), untrusted::Input::from(signature), ) } } pub(crate) fn verify_rsa_( params: &RsaParameters, (n, e): (untrusted::Input, untrusted::Input), msg: untrusted::Input, signature: untrusted::Input, ) -> Result<(), error::Unspecified> { let max_bits = bits::BitLength::from_usize_bytes(PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN)?; // XXX: FIPS 186-4 seems to indicate that the minimum // exponent value is 2**16 + 1, but it isn't clear if this is just for // signing or also for verification. We support exponents of 3 and larger // for compatibility with other commonly-used crypto libraries. let Key { n, e, n_bits } = Key::from_modulus_and_exponent(n, e, params.min_bits, max_bits, 3)?; // The signature must be the same length as the modulus, in bytes. if signature.len() != n_bits.as_usize_bytes_rounded_up() { return Err(error::Unspecified); } // RFC 8017 Section 5.2.2: RSAVP1. // Step 1. let s = bigint::Elem::from_be_bytes_padded(signature, &n)?; if s.is_zero() { return Err(error::Unspecified); } // Step 2. let m = bigint::elem_exp_vartime(s, e, &n); let m = m.into_unencoded(&n); // Step 3. let mut decoded = [0u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN]; let decoded = fill_be_bytes_n(m, n_bits, &mut decoded); // Verify the padded message is correct. let m_hash = digest::digest(params.padding_alg.digest_alg(), msg.as_slice_less_safe()); untrusted::Input::from(decoded).read_all(error::Unspecified, |m| { params.padding_alg.verify(&m_hash, m, n_bits) }) } /// Returns the big-endian representation of `elem` that is /// the same length as the minimal-length big-endian representation of /// the modulus `n`. /// /// `n_bits` must be the bit length of the public modulus `n`. fn fill_be_bytes_n( elem: bigint::Elem, n_bits: bits::BitLength, out: &mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN], ) -> &[u8] { let n_bytes = n_bits.as_usize_bytes_rounded_up(); let n_bytes_padded = ((n_bytes + (LIMB_BYTES - 1)) / LIMB_BYTES) * LIMB_BYTES; let out = &mut out[..n_bytes_padded]; elem.fill_be_bytes(out); let (padding, out) = out.split_at(n_bytes_padded - n_bytes); assert!(padding.iter().all(|&b| b == 0)); out }