ring/signature.rs
1// Copyright 2015-2017 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//! Public key signatures: signing and verification.
16//!
17//! Use the `verify` function to verify signatures, passing a reference to the
18//! algorithm that identifies the algorithm. See the documentation for `verify`
19//! for examples.
20//!
21//! For signature verification, this API treats each combination of parameters
22//! as a separate algorithm. For example, instead of having a single "RSA"
23//! algorithm with a verification function that takes a bunch of parameters,
24//! there are `RSA_PKCS1_2048_8192_SHA256`, `RSA_PKCS1_2048_8192_SHA384`, etc.,
25//! which encode sets of parameter choices into objects. This is designed to
26//! reduce the risks of algorithm agility and to provide consistency with ECDSA
27//! and EdDSA.
28//!
29//! Currently this module does not support digesting the message to be signed
30//! separately from the public key operation, as it is currently being
31//! optimized for Ed25519 and for the implementation of protocols that do not
32//! requiring signing large messages. An interface for efficiently supporting
33//! larger messages may be added later.
34//!
35//!
36//! # Algorithm Details
37//!
38//! ## `ECDSA_*_ASN1` Details: ASN.1-encoded ECDSA Signatures
39//!
40//! The signature is a ASN.1 DER-encoded `Ecdsa-Sig-Value` as described in
41//! [RFC 3279 Section 2.2.3]. This is the form of ECDSA signature used in
42//! X.509-related structures and in TLS's `ServerKeyExchange` messages.
43//!
44//! The public key is encoding in uncompressed form using the
45//! Octet-String-to-Elliptic-Curve-Point algorithm in
46//! [SEC 1: Elliptic Curve Cryptography, Version 2.0].
47//!
48//! During verification, the public key is validated using the ECC Partial
49//! Public-Key Validation Routine from Section 5.6.2.3.3 of
50//! [NIST Special Publication 800-56A, revision 2] and Appendix A.3 of the
51//! NSA's [Suite B implementer's guide to FIPS 186-3]. Note that, as explained
52//! in the NSA guide, ECC Partial Public-Key Validation is equivalent to ECC
53//! Full Public-Key Validation for prime-order curves like this one.
54//!
55//! ## `ECDSA_*_FIXED` Details: Fixed-length (PKCS#11-style) ECDSA Signatures
56//!
57//! The signature is *r*||*s*, where || denotes concatenation, and where both
58//! *r* and *s* are both big-endian-encoded values that are left-padded to the
59//! maximum length. A P-256 signature will be 64 bytes long (two 32-byte
60//! components) and a P-384 signature will be 96 bytes long (two 48-byte
61//! components). This is the form of ECDSA signature used PKCS#11 and DNSSEC.
62//!
63//! The public key is encoding in uncompressed form using the
64//! Octet-String-to-Elliptic-Curve-Point algorithm in
65//! [SEC 1: Elliptic Curve Cryptography, Version 2.0].
66//!
67//! During verification, the public key is validated using the ECC Partial
68//! Public-Key Validation Routine from Section 5.6.2.3.3 of
69//! [NIST Special Publication 800-56A, revision 2] and Appendix A.3 of the
70//! NSA's [Suite B implementer's guide to FIPS 186-3]. Note that, as explained
71//! in the NSA guide, ECC Partial Public-Key Validation is equivalent to ECC
72//! Full Public-Key Validation for prime-order curves like this one.
73//!
74//! ## `RSA_PKCS1_*` Details: RSA PKCS#1 1.5 Signatures
75//!
76//! The signature is an RSASSA-PKCS1-v1_5 signature as described in
77//! [RFC 3447 Section 8.2].
78//!
79//! The public key is encoded as an ASN.1 `RSAPublicKey` as described in
80//! [RFC 3447 Appendix-A.1.1]. The public key modulus length, rounded *up* to
81//! the nearest (larger) multiple of 8 bits, must be in the range given in the
82//! name of the algorithm. The public exponent must be an odd integer of 2-33
83//! bits, inclusive.
84//!
85//!
86//! ## `RSA_PSS_*` Details: RSA PSS Signatures
87//!
88//! The signature is an RSASSA-PSS signature as described in
89//! [RFC 3447 Section 8.1].
90//!
91//! The public key is encoded as an ASN.1 `RSAPublicKey` as described in
92//! [RFC 3447 Appendix-A.1.1]. The public key modulus length, rounded *up* to
93//! the nearest (larger) multiple of 8 bits, must be in the range given in the
94//! name of the algorithm. The public exponent must be an odd integer of 2-33
95//! bits, inclusive.
96//!
97//! During verification, signatures will only be accepted if the MGF1 digest
98//! algorithm is the same as the message digest algorithm and if the salt
99//! length is the same length as the message digest. This matches the
100//! requirements in TLS 1.3 and other recent specifications.
101//!
102//! During signing, the message digest algorithm will be used as the MGF1
103//! digest algorithm. The salt will be the same length as the message digest.
104//! This matches the requirements in TLS 1.3 and other recent specifications.
105//! Additionally, the entire salt is randomly generated separately for each
106//! signature using the secure random number generator passed to `sign()`.
107//!
108//!
109//! [SEC 1: Elliptic Curve Cryptography, Version 2.0]:
110//! http://www.secg.org/sec1-v2.pdf
111//! [NIST Special Publication 800-56A, revision 2]:
112//! http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf
113//! [Suite B implementer's guide to FIPS 186-3]:
114//! https://github.com/briansmith/ring/blob/main/doc/ecdsa.pdf
115//! [RFC 3279 Section 2.2.3]:
116//! https://tools.ietf.org/html/rfc3279#section-2.2.3
117//! [RFC 3447 Section 8.2]:
118//! https://tools.ietf.org/html/rfc3447#section-7.2
119//! [RFC 3447 Section 8.1]:
120//! https://tools.ietf.org/html/rfc3447#section-8.1
121//! [RFC 3447 Appendix-A.1.1]:
122//! https://tools.ietf.org/html/rfc3447#appendix-A.1.1
123//!
124//!
125//! # Examples
126//!
127//! ## Signing and verifying with Ed25519
128//!
129//! ```
130//! use ring::{
131//! rand,
132//! signature::{self, KeyPair},
133//! };
134//!
135//! # fn main() -> Result<(), ring::error::Unspecified> {
136//! // Generate a key pair in PKCS#8 (v2) format.
137//! let rng = rand::SystemRandom::new();
138//! let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng)?;
139//!
140//! // Normally the application would store the PKCS#8 file persistently. Later
141//! // it would read the PKCS#8 file from persistent storage to use it.
142//!
143//! let key_pair = signature::Ed25519KeyPair::from_pkcs8(pkcs8_bytes.as_ref())?;
144//!
145//! // Sign the message "hello, world".
146//! const MESSAGE: &[u8] = b"hello, world";
147//! let sig = key_pair.sign(MESSAGE);
148//!
149//! // Normally an application would extract the bytes of the signature and
150//! // send them in a protocol message to the peer(s). Here we just get the
151//! // public key key directly from the key pair.
152//! let peer_public_key_bytes = key_pair.public_key().as_ref();
153//!
154//! // Verify the signature of the message using the public key. Normally the
155//! // verifier of the message would parse the inputs to this code out of the
156//! // protocol message(s) sent by the signer.
157//! let peer_public_key =
158//! signature::UnparsedPublicKey::new(&signature::ED25519, peer_public_key_bytes);
159//! peer_public_key.verify(MESSAGE, sig.as_ref())?;
160//!
161//! # Ok(())
162//! # }
163//! ```
164//!
165//! ## Signing and verifying with RSA (PKCS#1 1.5 padding)
166//!
167//! By default OpenSSL writes RSA public keys in SubjectPublicKeyInfo format,
168//! not RSAPublicKey format, and Base64-encodes them (“PEM” format).
169//!
170//! To convert the PEM SubjectPublicKeyInfo format (“BEGIN PUBLIC KEY”) to the
171//! binary RSAPublicKey format needed by `verify()`, use:
172//!
173//! ```sh
174//! openssl rsa -pubin \
175//! -in public_key.pem \
176//! -inform PEM \
177//! -RSAPublicKey_out \
178//! -outform DER \
179//! -out public_key.der
180//! ```
181//!
182//! To extract the RSAPublicKey-formatted public key from an ASN.1 (binary)
183//! DER-encoded RSAPrivateKey format private key file, use:
184//!
185//! ```sh
186//! openssl rsa -in private_key.der \
187//! -inform DER \
188//! -RSAPublicKey_out \
189//! -outform DER \
190//! -out public_key.der
191//! ```
192//!
193//! ```
194//! use ring::{rand, signature};
195//!
196//! # #[cfg(feature = "std")]
197//! fn sign_and_verify_rsa(private_key_path: &std::path::Path,
198//! public_key_path: &std::path::Path)
199//! -> Result<(), MyError> {
200//! // Create an `RsaKeyPair` from the DER-encoded bytes. This example uses
201//! // a 2048-bit key, but larger keys are also supported.
202//! let private_key_der = read_file(private_key_path)?;
203//! let key_pair = signature::RsaKeyPair::from_der(&private_key_der)
204//! .map_err(|_| MyError::BadPrivateKey)?;
205//!
206//! // Sign the message "hello, world", using PKCS#1 v1.5 padding and the
207//! // SHA256 digest algorithm.
208//! const MESSAGE: &'static [u8] = b"hello, world";
209//! let rng = rand::SystemRandom::new();
210//! let mut signature = vec![0; key_pair.public_modulus_len()];
211//! key_pair.sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature)
212//! .map_err(|_| MyError::OOM)?;
213//!
214//! // Verify the signature.
215//! let public_key =
216//! signature::UnparsedPublicKey::new(&signature::RSA_PKCS1_2048_8192_SHA256,
217//! read_file(public_key_path)?);
218//! public_key.verify(MESSAGE, &signature)
219//! .map_err(|_| MyError::BadSignature)
220//! }
221//!
222//! #[derive(Debug)]
223//! enum MyError {
224//! # #[cfg(feature = "std")]
225//! IO(std::io::Error),
226//! BadPrivateKey,
227//! OOM,
228//! BadSignature,
229//! }
230//!
231//! # #[cfg(feature = "std")]
232//! fn read_file(path: &std::path::Path) -> Result<Vec<u8>, MyError> {
233//! use std::io::Read;
234//!
235//! let mut file = std::fs::File::open(path).map_err(|e| MyError::IO(e))?;
236//! let mut contents: Vec<u8> = Vec::new();
237//! file.read_to_end(&mut contents).map_err(|e| MyError::IO(e))?;
238//! Ok(contents)
239//! }
240//! #
241//! # #[cfg(not(feature = "std"))]
242//! # fn sign_and_verify_rsa(_private_key_path: &std::path::Path,
243//! # _public_key_path: &std::path::Path)
244//! # -> Result<(), ()> {
245//! # Ok(())
246//! # }
247//! #
248//! # fn main() {
249//! # let private_key_path =
250//! # std::path::Path::new("src/rsa/signature_rsa_example_private_key.der");
251//! # let public_key_path =
252//! # std::path::Path::new("src/rsa/signature_rsa_example_public_key.der");
253//! # sign_and_verify_rsa(&private_key_path, &public_key_path).unwrap()
254//! # }
255//! ```
256
257use crate::{cpu, ec, error, sealed};
258
259pub use crate::ec::{
260 curve25519::ed25519::{
261 signing::Ed25519KeyPair,
262 verification::{EdDSAParameters, ED25519},
263 ED25519_PUBLIC_KEY_LEN,
264 },
265 suite_b::ecdsa::{
266 signing::{
267 EcdsaKeyPair, EcdsaSigningAlgorithm, ECDSA_P256_SHA256_ASN1_SIGNING,
268 ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P384_SHA384_ASN1_SIGNING,
269 ECDSA_P384_SHA384_FIXED_SIGNING,
270 },
271 verification::{
272 EcdsaVerificationAlgorithm, ECDSA_P256_SHA256_ASN1, ECDSA_P256_SHA256_FIXED,
273 ECDSA_P256_SHA384_ASN1, ECDSA_P384_SHA256_ASN1, ECDSA_P384_SHA384_ASN1,
274 ECDSA_P384_SHA384_FIXED,
275 },
276 },
277};
278
279#[cfg(feature = "alloc")]
280pub use crate::rsa::{
281 signing::RsaKeyPair,
282 signing::RsaSubjectPublicKey,
283
284 verification::{
285 RsaPublicKeyComponents, RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
286 RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY,
287 RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY,
288 RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY, RSA_PKCS1_2048_8192_SHA256,
289 RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512, RSA_PKCS1_3072_8192_SHA384,
290 RSA_PSS_2048_8192_SHA256, RSA_PSS_2048_8192_SHA384, RSA_PSS_2048_8192_SHA512,
291 },
292
293 RsaEncoding,
294 RsaParameters,
295
296 // `RSA_PKCS1_SHA1` is intentionally not exposed. At a minimum, we'd need
297 // to create test vectors for signing with it, which we don't currently
298 // have. But, it's a bad idea to use SHA-1 anyway, so perhaps we just won't
299 // ever expose it.
300 RSA_PKCS1_SHA256,
301 RSA_PKCS1_SHA384,
302 RSA_PKCS1_SHA512,
303
304 RSA_PSS_SHA256,
305 RSA_PSS_SHA384,
306 RSA_PSS_SHA512,
307};
308
309/// A public key signature returned from a signing operation.
310#[derive(Clone, Copy)]
311pub struct Signature {
312 value: [u8; MAX_LEN],
313 len: usize,
314}
315
316impl Signature {
317 // Panics if `value` is too long.
318 pub(crate) fn new<F>(fill: F) -> Self
319 where
320 F: FnOnce(&mut [u8; MAX_LEN]) -> usize,
321 {
322 let mut r = Self {
323 value: [0; MAX_LEN],
324 len: 0,
325 };
326 r.len = fill(&mut r.value);
327 r
328 }
329}
330
331impl AsRef<[u8]> for Signature {
332 fn as_ref(&self) -> &[u8] {
333 &self.value[..self.len]
334 }
335}
336
337/// Key pairs for signing messages (private key and public key).
338pub trait KeyPair: core::fmt::Debug + Send + Sized + Sync {
339 /// The type of the public key.
340 type PublicKey: AsRef<[u8]> + core::fmt::Debug + Clone + Send + Sized + Sync;
341
342 /// The public key for the key pair.
343 fn public_key(&self) -> &Self::PublicKey;
344}
345
346/// The longest signature is an ASN.1 P-384 signature where *r* and *s* are of
347/// maximum length with the leading high bit set on each. Then each component
348/// will have a tag, a one-byte length, and a one-byte “I'm not negative”
349/// prefix, and the outer sequence will have a two-byte length.
350pub(crate) const MAX_LEN: usize = 1/*tag:SEQUENCE*/ + 2/*len*/ +
351 (2 * (1/*tag:INTEGER*/ + 1/*len*/ + 1/*zero*/ + ec::SCALAR_MAX_BYTES));
352
353/// A signature verification algorithm.
354pub trait VerificationAlgorithm: core::fmt::Debug + Sync + sealed::Sealed {
355 /// Verify the signature `signature` of message `msg` with the public key
356 /// `public_key`.
357 fn verify(
358 &self,
359 public_key: untrusted::Input,
360 msg: untrusted::Input,
361 signature: untrusted::Input,
362 ) -> Result<(), error::Unspecified>;
363}
364
365/// An unparsed, possibly malformed, public key for signature verification.
366pub struct UnparsedPublicKey<B: AsRef<[u8]>> {
367 algorithm: &'static dyn VerificationAlgorithm,
368 bytes: B,
369}
370
371impl<B: Copy> Copy for UnparsedPublicKey<B> where B: AsRef<[u8]> {}
372
373impl<B: Clone> Clone for UnparsedPublicKey<B>
374where
375 B: AsRef<[u8]>,
376{
377 fn clone(&self) -> Self {
378 Self {
379 algorithm: self.algorithm,
380 bytes: self.bytes.clone(),
381 }
382 }
383}
384
385impl<B: AsRef<[u8]>> UnparsedPublicKey<B> {
386 /// Construct a new `UnparsedPublicKey`.
387 ///
388 /// No validation of `bytes` is done until `verify()` is called.
389 #[inline]
390 pub fn new(algorithm: &'static dyn VerificationAlgorithm, bytes: B) -> Self {
391 Self { algorithm, bytes }
392 }
393
394 /// Parses the public key and verifies `signature` is a valid signature of
395 /// `message` using it.
396 ///
397 /// See the [crate::signature] module-level documentation for examples.
398 pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified> {
399 let _ = cpu::features();
400 self.algorithm.verify(
401 untrusted::Input::from(self.bytes.as_ref()),
402 untrusted::Input::from(message),
403 untrusted::Input::from(signature),
404 )
405 }
406}