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::{
18 parse_public_key, public_key, PublicExponent, RsaParameters, PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN,
19};
20use crate::{
21 bits::{self, FromUsizeBytes as _},
22 cpu, digest, error, sealed, signature,
23};
24
25impl signature::VerificationAlgorithm for RsaParameters {
26 fn verify(
27 &self,
28 public_key: untrusted::Input,
29 msg: untrusted::Input,
30 signature: untrusted::Input,
31 ) -> Result<(), error::Unspecified> {
32 let (n: Positive<'_>, e: Positive<'_>) = parse_public_key(input:public_key)?;
33 verify_rsa_(
34 self,
35 (
36 n.big_endian_without_leading_zero_as_input(),
37 e.big_endian_without_leading_zero_as_input(),
38 ),
39 msg,
40 signature,
41 cpu_features:cpu::features(),
42 )
43 }
44}
45
46impl sealed::Sealed for RsaParameters {}
47
48macro_rules! rsa_params {
49 ( $VERIFY_ALGORITHM:ident, $min_bits:expr, $PADDING_ALGORITHM:expr,
50 $doc_str:expr ) => {
51 #[doc=$doc_str]
52 ///
53 /// Only available in `alloc` mode.
54 pub static $VERIFY_ALGORITHM: RsaParameters = RsaParameters {
55 padding_alg: $PADDING_ALGORITHM,
56 min_bits: bits::BitLength::from_usize_bits($min_bits),
57 };
58 };
59}
60
61rsa_params!(
62 RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
63 1024,
64 &super::padding::RSA_PKCS1_SHA1_FOR_LEGACY_USE_ONLY,
65 "Verification of signatures using RSA keys of 1024-8192 bits,
66 PKCS#1.5 padding, and SHA-1.\n\nSee \"`RSA_PKCS1_*` Details\" in
67 `ring::signature`'s module-level documentation for more details."
68);
69rsa_params!(
70 RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY,
71 2048,
72 &super::padding::RSA_PKCS1_SHA1_FOR_LEGACY_USE_ONLY,
73 "Verification of signatures using RSA keys of 2048-8192 bits,
74 PKCS#1.5 padding, and SHA-1.\n\nSee \"`RSA_PKCS1_*` Details\" in
75 `ring::signature`'s module-level documentation for more details."
76);
77rsa_params!(
78 RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY,
79 1024,
80 &super::padding::RSA_PKCS1_SHA256,
81 "Verification of signatures using RSA keys of 1024-8192 bits,
82 PKCS#1.5 padding, and SHA-256.\n\nSee \"`RSA_PKCS1_*` Details\" in
83 `ring::signature`'s module-level documentation for more details."
84);
85rsa_params!(
86 RSA_PKCS1_2048_8192_SHA256,
87 2048,
88 &super::padding::RSA_PKCS1_SHA256,
89 "Verification of signatures using RSA keys of 2048-8192 bits,
90 PKCS#1.5 padding, and SHA-256.\n\nSee \"`RSA_PKCS1_*` Details\" in
91 `ring::signature`'s module-level documentation for more details."
92);
93rsa_params!(
94 RSA_PKCS1_2048_8192_SHA384,
95 2048,
96 &super::padding::RSA_PKCS1_SHA384,
97 "Verification of signatures using RSA keys of 2048-8192 bits,
98 PKCS#1.5 padding, and SHA-384.\n\nSee \"`RSA_PKCS1_*` Details\" in
99 `ring::signature`'s module-level documentation for more details."
100);
101rsa_params!(
102 RSA_PKCS1_2048_8192_SHA512,
103 2048,
104 &super::padding::RSA_PKCS1_SHA512,
105 "Verification of signatures using RSA keys of 2048-8192 bits,
106 PKCS#1.5 padding, and SHA-512.\n\nSee \"`RSA_PKCS1_*` Details\" in
107 `ring::signature`'s module-level documentation for more details."
108);
109rsa_params!(
110 RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY,
111 1024,
112 &super::padding::RSA_PKCS1_SHA512,
113 "Verification of signatures using RSA keys of 1024-8192 bits,
114 PKCS#1.5 padding, and SHA-512.\n\nSee \"`RSA_PKCS1_*` Details\" in
115 `ring::signature`'s module-level documentation for more details."
116);
117rsa_params!(
118 RSA_PKCS1_3072_8192_SHA384,
119 3072,
120 &super::padding::RSA_PKCS1_SHA384,
121 "Verification of signatures using RSA keys of 3072-8192 bits,
122 PKCS#1.5 padding, and SHA-384.\n\nSee \"`RSA_PKCS1_*` Details\" in
123 `ring::signature`'s module-level documentation for more details."
124);
125
126rsa_params!(
127 RSA_PSS_2048_8192_SHA256,
128 2048,
129 &super::padding::RSA_PSS_SHA256,
130 "Verification of signatures using RSA keys of 2048-8192 bits,
131 PSS padding, and SHA-256.\n\nSee \"`RSA_PSS_*` Details\" in
132 `ring::signature`'s module-level documentation for more details."
133);
134rsa_params!(
135 RSA_PSS_2048_8192_SHA384,
136 2048,
137 &super::padding::RSA_PSS_SHA384,
138 "Verification of signatures using RSA keys of 2048-8192 bits,
139 PSS padding, and SHA-384.\n\nSee \"`RSA_PSS_*` Details\" in
140 `ring::signature`'s module-level documentation for more details."
141);
142rsa_params!(
143 RSA_PSS_2048_8192_SHA512,
144 2048,
145 &super::padding::RSA_PSS_SHA512,
146 "Verification of signatures using RSA keys of 2048-8192 bits,
147 PSS padding, and SHA-512.\n\nSee \"`RSA_PSS_*` Details\" in
148 `ring::signature`'s module-level documentation for more details."
149);
150
151pub use super::PublicKeyComponents as RsaPublicKeyComponents;
152
153impl<B> super::PublicKeyComponents<B>
154where
155 B: AsRef<[u8]>,
156{
157 /// Verifies that `signature` is a valid signature of `message` using `self`
158 /// as the public key. `params` determine what algorithm parameters
159 /// (padding, digest algorithm, key length range, etc.) are used in the
160 /// verification.
161 ///
162 /// When the public key is in DER-encoded PKCS#1 ASN.1 format, it is
163 /// recommended to use `ring::signature::verify()` with
164 /// `ring::signature::RSA_PKCS1_*`, because `ring::signature::verify()`
165 /// will handle the parsing in that case. Otherwise, this function can be used
166 /// to pass in the raw bytes for the public key components as
167 /// `untrusted::Input` arguments.
168 //
169 // There are a small number of tests that test this directly, but the
170 // test coverage for this function mostly depends on the test coverage for the
171 // `signature::VerificationAlgorithm` implementation for `RsaParameters`. If we
172 // change that, test coverage for `verify_rsa()` will need to be reconsidered.
173 // (The NIST test vectors were originally in a form that was optimized for
174 // testing `verify_rsa` directly, but the testing work for RSA PKCS#1
175 // verification was done during the implementation of
176 // `signature::VerificationAlgorithm`, before `verify_rsa` was factored out).
177 pub fn verify(
178 &self,
179 params: &RsaParameters,
180 message: &[u8],
181 signature: &[u8],
182 ) -> Result<(), error::Unspecified> {
183 verify_rsa_(
184 params,
185 (
186 untrusted::Input::from(self.n.as_ref()),
187 untrusted::Input::from(self.e.as_ref()),
188 ),
189 untrusted::Input::from(message),
190 untrusted::Input::from(signature),
191 cpu::features(),
192 )
193 }
194}
195
196pub(crate) fn verify_rsa_(
197 params: &RsaParameters,
198 (n: Input<'_>, e: Input<'_>): (untrusted::Input, untrusted::Input),
199 msg: untrusted::Input,
200 signature: untrusted::Input,
201 cpu_features: cpu::Features,
202) -> Result<(), error::Unspecified> {
203 let max_bits: bits::BitLength =
204 bits::BitLength::from_usize_bytes(PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN)?;
205
206 // XXX: FIPS 186-4 seems to indicate that the minimum
207 // exponent value is 2**16 + 1, but it isn't clear if this is just for
208 // signing or also for verification. We support exponents of 3 and larger
209 // for compatibility with other commonly-used crypto libraries.
210 let key = public_key::Inner::from_modulus_and_exponent(
211 n,
212 e,
213 params.min_bits,
214 max_bits,
215 PublicExponent::_3,
216 cpu_features,
217 )?;
218
219 // RFC 8017 Section 5.2.2: RSAVP1.
220 let mut decoded = [0u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN];
221 let decoded = key.exponentiate(signature, &mut decoded, cpu_features)?;
222
223 // Verify the padded message is correct.
224 let m_hash = digest::digest(params.padding_alg.digest_alg(), msg.as_slice_less_safe());
225 untrusted::Input::from(decoded).read_all(error::Unspecified, |m| {
226 params.padding_alg.verify(m_hash, m, key.n().len_bits())
227 })
228}
229