| 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 | |