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, FromUsizeBytes as _}, |
22 | cpu, digest, error, sealed, signature, |
23 | }; |
24 | |
25 | impl 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 | |
46 | impl sealed::Sealed for RsaParameters {} |
47 | |
48 | macro_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 | |
61 | rsa_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 | ); |
69 | rsa_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 | ); |
77 | rsa_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 | ); |
85 | rsa_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 | ); |
93 | rsa_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 | ); |
101 | rsa_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 | ); |
109 | rsa_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 | ); |
117 | rsa_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 | |
126 | rsa_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 | ); |
134 | rsa_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 | ); |
142 | rsa_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 | |
151 | pub use super::PublicKeyComponents as RsaPublicKeyComponents; |
152 | |
153 | impl<B> super::PublicKeyComponents<B> |
154 | where |
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 | |
196 | pub(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 | |