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