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//! # #[cfg(feature = "std")]
195//! use ring::{rand, rsa, signature};
196//!
197//! # #[cfg(feature = "std")]
198//! fn sign_and_verify_rsa(private_key_path: &std::path::Path,
199//! public_key_path: &std::path::Path)
200//! -> Result<(), MyError> {
201//! // Create an RSA keypair from the DER-encoded bytes. This example uses
202//! // a 2048-bit key, but larger keys are also supported.
203//! let private_key_der = read_file(private_key_path)?;
204//! let key_pair = rsa::KeyPair::from_der(&private_key_der)
205//! .map_err(|_| MyError::BadPrivateKey)?;
206//!
207//! // Sign the message "hello, world", using PKCS#1 v1.5 padding and the
208//! // SHA256 digest algorithm.
209//! const MESSAGE: &'static [u8] = b"hello, world";
210//! let rng = rand::SystemRandom::new();
211//! let mut signature = vec![0; key_pair.public().modulus_len()];
212//! key_pair.sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature)
213//! .map_err(|_| MyError::OOM)?;
214//!
215//! // Verify the signature.
216//! let public_key =
217//! signature::UnparsedPublicKey::new(&signature::RSA_PKCS1_2048_8192_SHA256,
218//! read_file(public_key_path)?);
219//! public_key.verify(MESSAGE, &signature)
220//! .map_err(|_| MyError::BadSignature)
221//! }
222//!
223//! #[derive(Debug)]
224//! enum MyError {
225//! # #[cfg(feature = "std")]
226//! IO(std::io::Error),
227//! BadPrivateKey,
228//! OOM,
229//! BadSignature,
230//! }
231//!
232//! # #[cfg(feature = "std")]
233//! fn read_file(path: &std::path::Path) -> Result<Vec<u8>, MyError> {
234//! use std::io::Read;
235//!
236//! let mut file = std::fs::File::open(path).map_err(|e| MyError::IO(e))?;
237//! let mut contents: Vec<u8> = Vec::new();
238//! file.read_to_end(&mut contents).map_err(|e| MyError::IO(e))?;
239//! Ok(contents)
240//! }
241//! #
242//! # #[cfg(not(feature = "std"))]
243//! # fn sign_and_verify_rsa(_private_key_path: &std::path::Path,
244//! # _public_key_path: &std::path::Path)
245//! # -> Result<(), ()> {
246//! # Ok(())
247//! # }
248//! #
249//! # fn main() {
250//! # let private_key_path =
251//! # std::path::Path::new("src/rsa/signature_rsa_example_private_key.der");
252//! # let public_key_path =
253//! # std::path::Path::new("src/rsa/signature_rsa_example_public_key.der");
254//! # sign_and_verify_rsa(&private_key_path, &public_key_path).unwrap()
255//! # }
256//! ```
257
258use crate::{cpu, debug, ec, error, sealed};
259
260pub use crate::ec::{
261 curve25519::ed25519::{
262 signing::Ed25519KeyPair,
263 verification::{EdDSAParameters, ED25519},
264 ED25519_PUBLIC_KEY_LEN,
265 },
266 suite_b::ecdsa::{
267 signing::{
268 EcdsaKeyPair, EcdsaSigningAlgorithm, ECDSA_P256_SHA256_ASN1_SIGNING,
269 ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P384_SHA384_ASN1_SIGNING,
270 ECDSA_P384_SHA384_FIXED_SIGNING,
271 },
272 verification::{
273 EcdsaVerificationAlgorithm, ECDSA_P256_SHA256_ASN1, ECDSA_P256_SHA256_FIXED,
274 ECDSA_P256_SHA384_ASN1, ECDSA_P384_SHA256_ASN1, ECDSA_P384_SHA384_ASN1,
275 ECDSA_P384_SHA384_FIXED,
276 },
277 },
278};
279
280#[cfg(feature = "alloc")]
281pub use crate::rsa::{
282 padding::{
283 RsaEncoding, RSA_PKCS1_SHA256, RSA_PKCS1_SHA384, RSA_PKCS1_SHA512, RSA_PSS_SHA256,
284 RSA_PSS_SHA384, RSA_PSS_SHA512,
285 },
286 verification::{
287 RsaPublicKeyComponents, RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
288 RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY,
289 RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY,
290 RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY, RSA_PKCS1_2048_8192_SHA256,
291 RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512, RSA_PKCS1_3072_8192_SHA384,
292 RSA_PSS_2048_8192_SHA256, RSA_PSS_2048_8192_SHA384, RSA_PSS_2048_8192_SHA512,
293 },
294 RsaParameters,
295};
296
297/// An RSA key pair, used for signing.
298#[cfg(feature = "alloc")]
299pub type RsaKeyPair = crate::rsa::KeyPair;
300
301/// A public key signature returned from a signing operation.
302#[derive(Clone, Copy)]
303pub struct Signature {
304 value: [u8; MAX_LEN],
305 len: usize,
306}
307
308impl Signature {
309 // Panics if `value` is too long.
310 pub(crate) fn new<F>(fill: F) -> Self
311 where
312 F: FnOnce(&mut [u8; MAX_LEN]) -> usize,
313 {
314 let mut r: Signature = Self {
315 value: [0; MAX_LEN],
316 len: 0,
317 };
318 r.len = fill(&mut r.value);
319 r
320 }
321}
322
323impl AsRef<[u8]> for Signature {
324 fn as_ref(&self) -> &[u8] {
325 &self.value[..self.len]
326 }
327}
328
329/// Key pairs for signing messages (private key and public key).
330pub trait KeyPair: core::fmt::Debug + Send + Sized + Sync {
331 /// The type of the public key.
332 type PublicKey: AsRef<[u8]> + core::fmt::Debug + Clone + Send + Sized + Sync;
333
334 /// The public key for the key pair.
335 fn public_key(&self) -> &Self::PublicKey;
336}
337
338/// The longest signature is an ASN.1 P-384 signature where *r* and *s* are of
339/// maximum length with the leading high bit set on each. Then each component
340/// will have a tag, a one-byte length, and a one-byte “I'm not negative”
341/// prefix, and the outer sequence will have a two-byte length.
342pub(crate) const MAX_LEN: usize = 1/*tag:SEQUENCE*/ + 2/*len*/ +
343 (2 * (1/*tag:INTEGER*/ + 1/*len*/ + 1/*zero*/ + ec::SCALAR_MAX_BYTES));
344
345/// A signature verification algorithm.
346pub trait VerificationAlgorithm: core::fmt::Debug + Sync + sealed::Sealed {
347 /// Verify the signature `signature` of message `msg` with the public key
348 /// `public_key`.
349 fn verify(
350 &self,
351 public_key: untrusted::Input,
352 msg: untrusted::Input,
353 signature: untrusted::Input,
354 ) -> Result<(), error::Unspecified>;
355}
356
357/// An unparsed, possibly malformed, public key for signature verification.
358#[derive(Clone, Copy)]
359pub struct UnparsedPublicKey<B> {
360 algorithm: &'static dyn VerificationAlgorithm,
361 bytes: B,
362}
363
364impl<B> AsRef<[u8]> for UnparsedPublicKey<B>
365where
366 B: AsRef<[u8]>,
367{
368 fn as_ref(&self) -> &[u8] {
369 self.bytes.as_ref()
370 }
371}
372
373impl<B: core::fmt::Debug> core::fmt::Debug for UnparsedPublicKey<B>
374where
375 B: AsRef<[u8]>,
376{
377 fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
378 f&mut DebugStruct<'_, '_>.debug_struct("UnparsedPublicKey")
379 .field("algorithm", &self.algorithm)
380 .field(name:"bytes", &debug::HexStr(self.bytes.as_ref()))
381 .finish()
382 }
383}
384
385impl<B> 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 where
400 B: AsRef<[u8]>,
401 {
402 let _ = cpu::features();
403 self.algorithm.verify(
404 untrusted::Input::from(self.bytes.as_ref()),
405 untrusted::Input::from(message),
406 untrusted::Input::from(signature),
407 )
408 }
409}
410