Skip to main content

aws_lc_rs/
signature.rs

1// Copyright 2015-2017 Brian Smith.
2// SPDX-License-Identifier: ISC
3// Modifications copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4// SPDX-License-Identifier: Apache-2.0 OR ISC
5
6//! Public key signatures: signing and verification.
7//!
8//! Use the `verify` function to verify signatures, passing a reference to the
9//! algorithm that identifies the algorithm. See the documentation for `verify`
10//! for examples.
11//!
12//! For signature verification, this API treats each combination of parameters
13//! as a separate algorithm. For example, instead of having a single "RSA"
14//! algorithm with a verification function that takes a bunch of parameters,
15//! there are `RSA_PKCS1_2048_8192_SHA256`, `RSA_PKCS1_2048_8192_SHA384`, etc.,
16//! which encode sets of parameter choices into objects. This is designed to
17//! reduce the risks of algorithm agility and to provide consistency with ECDSA
18//! and `EdDSA`.
19//!
20//! Currently this module does not support digesting the message to be signed
21//! separately from the public key operation, as it is currently being
22//! optimized for Ed25519 and for the implementation of protocols that do not
23//! requiring signing large messages. An interface for efficiently supporting
24//! larger messages may be added later.
25//!
26//!
27//! # Algorithm Details
28//!
29//! ## `ECDSA_*_ASN1` Details: ASN.1-encoded ECDSA Signatures
30//!
31//! The signature is a ASN.1 DER-encoded `Ecdsa-Sig-Value` as described in
32//! [RFC 3279 Section 2.2.3]. This is the form of ECDSA signature used in
33//! X.509-related structures and in TLS's `ServerKeyExchange` messages.
34//!
35//! The public key is encoding in uncompressed form using the
36//! Octet-String-to-Elliptic-Curve-Point algorithm in
37//! [SEC 1: Elliptic Curve Cryptography, Version 2.0].
38//!
39//! During verification, the public key is validated using the ECC Partial
40//! Public-Key Validation Routine from Section 5.6.2.3.3 of
41//! [NIST Special Publication 800-56A, revision 2] and Appendix A.3 of the
42//! NSA's [Suite B implementer's guide to FIPS 186-3]. Note that, as explained
43//! in the NSA guide, ECC Partial Public-Key Validation is equivalent to ECC
44//! Full Public-Key Validation for prime-order curves like this one.
45//!
46//! ## `ECDSA_*_FIXED` Details: Fixed-length (PKCS#11-style) ECDSA Signatures
47//!
48//! The signature is *r*||*s*, where || denotes concatenation, and where both
49//! *r* and *s* are both big-endian-encoded values that are left-padded to the
50//! maximum length. A P-256 signature will be 64 bytes long (two 32-byte
51//! components) and a P-384 signature will be 96 bytes long (two 48-byte
52//! components). This is the form of ECDSA signature used PKCS#11 and DNSSEC.
53//!
54//! The public key is encoding in uncompressed form using the
55//! Octet-String-to-Elliptic-Curve-Point algorithm in
56//! [SEC 1: Elliptic Curve Cryptography, Version 2.0].
57//!
58//! During verification, the public key is validated using the ECC Partial
59//! Public-Key Validation Routine from Section 5.6.2.3.3 of
60//! [NIST Special Publication 800-56A, revision 2] and Appendix A.3 of the
61//! NSA's [Suite B implementer's guide to FIPS 186-3]. Note that, as explained
62//! in the NSA guide, ECC Partial Public-Key Validation is equivalent to ECC
63//! Full Public-Key Validation for prime-order curves like this one.
64//!
65//! ## `RSA_PKCS1_*` Details: RSA PKCS#1 1.5 Signatures
66//!
67//! The signature is an RSASSA-PKCS1-v1_5 signature as described in
68//! [RFC 3447 Section 8.2].
69//!
70//! The public key is encoded as an ASN.1 `RSAPublicKey` as described in
71//! [RFC 3447 Appendix-A.1.1]. The public key modulus length, rounded *up* to
72//! the nearest (larger) multiple of 8 bits, must be in the range given in the
73//! name of the algorithm. The public exponent must be an odd integer of 2-33
74//! bits, inclusive.
75//!
76//!
77//! ## `RSA_PSS_*` Details: RSA PSS Signatures
78//!
79//! The signature is an RSASSA-PSS signature as described in
80//! [RFC 3447 Section 8.1].
81//!
82//! The public key is encoded as an ASN.1 `RSAPublicKey` as described in
83//! [RFC 3447 Appendix-A.1.1]. The public key modulus length, rounded *up* to
84//! the nearest (larger) multiple of 8 bits, must be in the range given in the
85//! name of the algorithm. The public exponent must be an odd integer of 2-33
86//! bits, inclusive.
87//!
88//! During verification, signatures will only be accepted if the MGF1 digest
89//! algorithm is the same as the message digest algorithm and if the salt
90//! length is the same length as the message digest. This matches the
91//! requirements in TLS 1.3 and other recent specifications.
92//!
93//! During signing, the message digest algorithm will be used as the MGF1
94//! digest algorithm. The salt will be the same length as the message digest.
95//! This matches the requirements in TLS 1.3 and other recent specifications.
96//! Additionally, the entire salt is randomly generated separately for each
97//! signature using the secure random number generator passed to `sign()`.
98//!
99//!
100//! [SEC 1: Elliptic Curve Cryptography, Version 2.0]:
101//!     http://www.secg.org/sec1-v2.pdf
102//! [NIST Special Publication 800-56A, revision 2]:
103//!     http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf
104//! [Suite B implementer's guide to FIPS 186-3]:
105//!     https://github.com/briansmith/ring/blob/main/doc/ecdsa.pdf
106//! [RFC 3279 Section 2.2.3]:
107//!     https://tools.ietf.org/html/rfc3279#section-2.2.3
108//! [RFC 3447 Section 8.2]:
109//!     https://tools.ietf.org/html/rfc3447#section-7.2
110//! [RFC 3447 Section 8.1]:
111//!     https://tools.ietf.org/html/rfc3447#section-8.1
112//! [RFC 3447 Appendix-A.1.1]:
113//!     https://tools.ietf.org/html/rfc3447#appendix-A.1.1
114//!
115//!
116//! # Examples
117//!
118//! ## Signing and verifying with Ed25519
119//!
120//! ```
121//! use aws_lc_rs::{
122//!     rand,
123//!     signature::{self, KeyPair},
124//! };
125//!
126//! fn main() -> Result<(), aws_lc_rs::error::Unspecified> {
127//!     // Generate a new key pair for Ed25519.
128//!     let key_pair = signature::Ed25519KeyPair::generate()?;
129//!
130//!     // Sign the message "hello, world".
131//!     const MESSAGE: &[u8] = b"hello, world";
132//!     let sig = key_pair.sign(MESSAGE);
133//!
134//!     // Normally an application would extract the bytes of the signature and
135//!     // send them in a protocol message to the peer(s). Here we just get the
136//!     // public key key directly from the key pair.
137//!     let peer_public_key_bytes = key_pair.public_key().as_ref();
138//!
139//!     // Verify the signature of the message using the public key. Normally the
140//!     // verifier of the message would parse the inputs to this code out of the
141//!     // protocol message(s) sent by the signer.
142//!     let peer_public_key =
143//!         signature::UnparsedPublicKey::new(&signature::ED25519, peer_public_key_bytes);
144//!     peer_public_key.verify(MESSAGE, sig.as_ref())?;
145//!
146//!     Ok(())
147//! }
148//! ```
149//!
150//! ## Signing and verifying with RSA (PKCS#1 1.5 padding)
151//!
152//! By default OpenSSL writes RSA public keys in `SubjectPublicKeyInfo` format,
153//! not `RSAPublicKey` format, and Base64-encodes them (“PEM” format).
154//!
155//! To convert the PEM `SubjectPublicKeyInfo` format (“BEGIN PUBLIC KEY”) to the
156//! binary `RSAPublicKey` format needed by `verify()`, use:
157//!
158//! ```sh
159//! openssl rsa -pubin \
160//!             -in public_key.pem \
161//!             -inform PEM \
162//!             -RSAPublicKey_out \
163//!             -outform DER \
164//!             -out public_key.der
165//! ```
166//!
167//! To extract the RSAPublicKey-formatted public key from an ASN.1 (binary)
168//! DER-encoded `RSAPrivateKey` format private key file, use:
169//!
170//! ```sh
171//! openssl rsa -in private_key.der \
172//!             -inform DER \
173//!             -RSAPublicKey_out \
174//!             -outform DER \
175//!             -out public_key.der
176//! ```
177//!
178//! ```
179//! use aws_lc_rs::{rand, signature};
180//!
181//! fn sign_and_verify_rsa(
182//!     private_key_path: &std::path::Path,
183//!     public_key_path: &std::path::Path,
184//! ) -> Result<(), MyError> {
185//!     // Create an `RsaKeyPair` from the DER-encoded bytes. This example uses
186//!     // a 2048-bit key, but larger keys are also supported.
187//!     let private_key_der = read_file(private_key_path)?;
188//!     let key_pair = signature::RsaKeyPair::from_der(&private_key_der)
189//!         .map_err(|_| MyError::BadPrivateKey)?;
190//!
191//!     // Sign the message "hello, world", using PKCS#1 v1.5 padding and the
192//!     // SHA256 digest algorithm.
193//!     const MESSAGE: &'static [u8] = b"hello, world";
194//!     let rng = rand::SystemRandom::new();
195//!     let mut signature = vec![0; key_pair.public_modulus_len()];
196//!     key_pair
197//!         .sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature)
198//!         .map_err(|_| MyError::OOM)?;
199//!
200//!     // Verify the signature.
201//!     let public_key = signature::UnparsedPublicKey::new(
202//!         &signature::RSA_PKCS1_2048_8192_SHA256,
203//!         read_file(public_key_path)?,
204//!     );
205//!     public_key
206//!         .verify(MESSAGE, &signature)
207//!         .map_err(|_| MyError::BadSignature)
208//! }
209//!
210//! #[derive(Debug)]
211//! enum MyError {
212//!     IO(std::io::Error),
213//!     BadPrivateKey,
214//!     OOM,
215//!     BadSignature,
216//! }
217//!
218//! fn read_file(path: &std::path::Path) -> Result<Vec<u8>, MyError> {
219//!     use std::io::Read;
220//!
221//!     let mut file = std::fs::File::open(path).map_err(|e| MyError::IO(e))?;
222//!     let mut contents: Vec<u8> = Vec::new();
223//!     file.read_to_end(&mut contents)
224//!         .map_err(|e| MyError::IO(e))?;
225//!     Ok(contents)
226//! }
227//!
228//! fn main() {
229//!     let private_key_path =
230//!         std::path::Path::new("tests/data/signature_rsa_example_private_key.der");
231//!     let public_key_path =
232//!         std::path::Path::new("tests/data/signature_rsa_example_public_key.der");
233//!     sign_and_verify_rsa(&private_key_path, &public_key_path).unwrap()
234//! }
235//! ```
236use crate::aws_lc::EVP_PKEY;
237pub use crate::rsa::signature::{RsaEncoding, RsaSignatureEncoding};
238pub use crate::rsa::{
239    KeyPair as RsaKeyPair, PublicKey as RsaSubjectPublicKey,
240    PublicKeyComponents as RsaPublicKeyComponents, RsaParameters,
241};
242use core::fmt::{Debug, Formatter};
243use std::any::{Any, TypeId};
244#[cfg(feature = "ring-sig-verify")]
245use untrusted::Input;
246
247use crate::rsa::signature::RsaSigningAlgorithmId;
248use crate::rsa::RsaVerificationAlgorithmId;
249
250pub use crate::ec::key_pair::{EcdsaKeyPair, PrivateKey as EcdsaPrivateKey};
251use crate::ec::signature::EcdsaSignatureFormat;
252pub use crate::ec::signature::{
253    EcdsaSigningAlgorithm, EcdsaVerificationAlgorithm, PublicKey as EcdsaPublicKey,
254};
255pub use crate::ed25519::{
256    Ed25519KeyPair, EdDSAParameters, PublicKey as Ed25519PublicKey, Seed as Ed25519Seed,
257    ED25519_PUBLIC_KEY_LEN,
258};
259
260use crate::digest::Digest;
261use crate::ec::encoding::parse_ec_public_key;
262use crate::ed25519::parse_ed25519_public_key;
263use crate::encoding::{AsDer, PublicKeyX509Der};
264use crate::error::{KeyRejected, Unspecified};
265#[cfg(all(feature = "unstable", not(feature = "fips")))]
266use crate::pqdsa::{parse_pqdsa_public_key, signature::PqdsaVerificationAlgorithm};
267use crate::ptr::LcPtr;
268use crate::rsa::key::parse_rsa_public_key;
269use crate::{digest, ec, error, hex, rsa, sealed};
270
271/// The longest signature is for ML-DSA-87
272pub(crate) const MAX_LEN: usize = 4627;
273
274/// A public key signature returned from a signing operation.
275#[derive(Clone, Copy)]
276pub struct Signature {
277    value: [u8; MAX_LEN],
278    len: usize,
279}
280
281impl Signature {
282    // Panics if `value` is too long.
283    pub(crate) fn new<F>(fill: F) -> Self
284    where
285        F: FnOnce(&mut [u8; MAX_LEN]) -> usize,
286    {
287        let mut r = Self {
288            value: [0; MAX_LEN],
289            len: 0,
290        };
291        r.len = fill(&mut r.value);
292        r
293    }
294}
295
296impl AsRef<[u8]> for Signature {
297    #[inline]
298    fn as_ref(&self) -> &[u8] {
299        &self.value[..self.len]
300    }
301}
302
303/// Key pairs for signing messages (private key and public key).
304pub trait KeyPair: Debug + Send + Sized + Sync {
305    /// The type of the public key.
306    type PublicKey: AsRef<[u8]> + Debug + Clone + Send + Sized + Sync;
307
308    /// The public key for the key pair.
309    fn public_key(&self) -> &Self::PublicKey;
310}
311
312// Private trait
313pub(crate) trait ParsedVerificationAlgorithm: Debug + Sync {
314    fn parsed_verify_sig(
315        &self,
316        public_key: &ParsedPublicKey,
317        msg: &[u8],
318        signature: &[u8],
319    ) -> Result<(), error::Unspecified>;
320
321    fn parsed_verify_digest_sig(
322        &self,
323        public_key: &ParsedPublicKey,
324        digest: &Digest,
325        signature: &[u8],
326    ) -> Result<(), error::Unspecified>;
327}
328
329/// A signature verification algorithm.
330pub trait VerificationAlgorithm: Debug + Sync + Any + sealed::Sealed {
331    /// Verify the signature `signature` of message `msg` with the public key
332    /// `public_key`.
333    ///
334    // # FIPS
335    // The following conditions must be met:
336    // * RSA Key Sizes: 1024, 2048, 3072, 4096
337    // * NIST Elliptic Curves: P256, P384, P521
338    // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
339    //
340    /// # Errors
341    /// `error::Unspecified` if inputs not verified.
342    #[cfg(feature = "ring-sig-verify")]
343    #[deprecated(note = "please use `VerificationAlgorithm::verify_sig` instead")]
344    fn verify(
345        &self,
346        public_key: Input<'_>,
347        msg: Input<'_>,
348        signature: Input<'_>,
349    ) -> Result<(), error::Unspecified>;
350
351    /// Verify the signature `signature` of message `msg` with the public key
352    /// `public_key`.
353    ///
354    // # FIPS
355    // The following conditions must be met:
356    // * RSA Key Sizes: 1024, 2048, 3072, 4096
357    // * NIST Elliptic Curves: P256, P384, P521
358    // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
359    //
360    /// # Errors
361    /// `error::Unspecified` if inputs not verified.
362    fn verify_sig(
363        &self,
364        public_key: &[u8],
365        msg: &[u8],
366        signature: &[u8],
367    ) -> Result<(), error::Unspecified>;
368
369    /// Verify the signature `signature` of `digest` with the `public_key`.
370    ///
371    // # FIPS
372    // Not approved.
373    //
374    /// # Errors
375    /// `error::Unspecified` if inputs not verified.
376    fn verify_digest_sig(
377        &self,
378        public_key: &[u8],
379        digest: &Digest,
380        signature: &[u8],
381    ) -> Result<(), error::Unspecified>;
382}
383
384/// An unparsed, possibly malformed, public key for signature verification.
385#[derive(Clone)]
386pub struct UnparsedPublicKey<B: AsRef<[u8]>> {
387    algorithm: &'static dyn VerificationAlgorithm,
388    bytes: B,
389}
390/// A parsed public key for signature verification.
391///
392/// A `ParsedPublicKey` can be created in two ways:
393/// - Directly from public key bytes using [`ParsedPublicKey::new`]
394/// - By parsing an `UnparsedPublicKey` using [`UnparsedPublicKey::parse`]
395///
396/// This pre-validates the public key format and stores the parsed key material,
397/// allowing for more efficient signature verification operations compared to
398/// parsing the key on each verification.
399///
400/// See the [`crate::signature`] module-level documentation for examples.
401#[derive(Clone)]
402pub struct ParsedPublicKey {
403    algorithm: &'static dyn VerificationAlgorithm,
404    parsed_algorithm: &'static dyn ParsedVerificationAlgorithm,
405    key: LcPtr<EVP_PKEY>,
406    bytes: Box<[u8]>,
407}
408
409// See EVP_PKEY documentation here:
410// https://github.com/aws/aws-lc/blob/125af14c57451565b875fbf1282a38a6ecf83782/include/openssl/evp.h#L83-L89
411// An |EVP_PKEY| object represents a public or private key. A given object may
412// be used concurrently on multiple threads by non-mutating functions, provided
413// no other thread is concurrently calling a mutating function. Unless otherwise
414// documented, functions which take a |const| pointer are non-mutating and
415// functions which take a non-|const| pointer are mutating.
416unsafe impl Send for ParsedPublicKey {}
417unsafe impl Sync for ParsedPublicKey {}
418
419impl ParsedPublicKey {
420    /// Creates a new `ParsedPublicKey` directly from public key bytes.
421    ///
422    /// This method validates the public key format and creates a `ParsedPublicKey`
423    /// that can be used for efficient signature verification operations.
424    ///
425    /// # Errors
426    /// `KeyRejected` if the public key bytes are malformed or incompatible
427    /// with the specified algorithm.
428    ///
429    /// # Examples
430    ///
431    /// ```
432    /// use aws_lc_rs::signature::{self, ParsedPublicKey};
433    ///
434    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
435    ///     let parsed_key = ParsedPublicKey::new(&signature::ED25519, include_bytes!("../tests/data/ed25519_test_public_key.bin"))?;
436    ///     let signature = [
437    ///         0xED, 0xDB, 0x67, 0xE9, 0xF7, 0x8C, 0x9A, 0x0, 0xFD, 0xEE, 0x2D, 0x22, 0x21, 0xA3, 0x9A,
438    ///         0x8A, 0x79, 0xF2, 0x53, 0x88, 0x78, 0xF0, 0xA0, 0x1, 0x80, 0xA, 0x49, 0xA4, 0x17, 0x88,
439    ///         0xAB, 0x44, 0x4B, 0xD2, 0x58, 0xB0, 0x3B, 0x51, 0x8A, 0x1B, 0x61, 0x24, 0x52, 0x78, 0x48,
440    ///         0x58, 0x40, 0x5, 0xB5, 0x45, 0x22, 0xB6, 0x40, 0xBD, 0x14, 0x47, 0xB1, 0xF0, 0xDC, 0x13,
441    ///         0xB3, 0xE9, 0xD0, 0x6,
442    ///     ];
443    ///     assert!(parsed_key.verify_sig(b"hello world!", &signature).is_ok());
444    ///     assert!(parsed_key.verify_sig(b"hello world.", &signature).is_err());
445    /// # Ok(())
446    /// # }
447    /// ```
448    pub fn new<B: AsRef<[u8]>>(
449        algorithm: &'static dyn VerificationAlgorithm,
450        bytes: B,
451    ) -> Result<Self, KeyRejected> {
452        parse_public_key(bytes.as_ref(), algorithm)
453    }
454
455    /// Returns the algorithm used by this public key.
456    #[must_use]
457    pub fn algorithm(&self) -> &'static dyn VerificationAlgorithm {
458        self.algorithm
459    }
460
461    pub(crate) fn key(&self) -> &LcPtr<EVP_PKEY> {
462        &self.key
463    }
464
465    /// Constructs a `ParsedPublicKey` directly from an already-built RSA
466    /// `EVP_PKEY`, skipping the DER-encode / DER-decode round-trip that
467    /// [`parse_public_key`] would otherwise perform. The SubjectPublicKeyInfo
468    /// DER is still marshalled once so that [`AsRef<[u8]>`] on the resulting
469    /// `ParsedPublicKey` continues to return a canonical encoding.
470    ///
471    /// `params` is used as both the public [`VerificationAlgorithm`] and the
472    /// internal `ParsedVerificationAlgorithm`, matching what
473    /// [`parse_public_key`] would assign for RSA inputs.
474    pub(crate) fn from_rsa_evp_pkey(
475        params: &'static RsaParameters,
476        key: LcPtr<EVP_PKEY>,
477    ) -> Result<Self, Unspecified> {
478        let bytes = key
479            .as_const()
480            .marshal_rfc5280_public_key()?
481            .into_boxed_slice();
482        Ok(ParsedPublicKey {
483            algorithm: params,
484            parsed_algorithm: params,
485            key,
486            bytes,
487        })
488    }
489
490    /// Uses the public key to verify that `signature` is a valid signature of
491    /// `message`.
492    ///
493    /// This method is more efficient than [`UnparsedPublicKey::verify`] when
494    /// performing multiple signature verifications with the same public key,
495    /// as the key parsing overhead is avoided.
496    ///
497    /// See the [`crate::signature`] module-level documentation for examples.
498    ///
499    // # FIPS
500    // The following conditions must be met:
501    // * RSA Key Sizes: 1024, 2048, 3072, 4096
502    // * NIST Elliptic Curves: P256, P384, P521
503    // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
504    //
505    /// # Errors
506    /// `error::Unspecified` if the signature is invalid or verification fails.
507    #[inline]
508    pub fn verify_sig(&self, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified> {
509        self.parsed_algorithm
510            .parsed_verify_sig(self, message, signature)
511    }
512
513    /// Uses the public key to verify that `signature` is a valid signature of
514    /// `digest`.
515    ///
516    /// This method is more efficient than [`UnparsedPublicKey::verify_digest`] when
517    /// performing multiple signature verifications with the same public key,
518    /// as the key parsing overhead is avoided.
519    ///
520    /// See the [`crate::signature`] module-level documentation for examples.
521    ///
522    // # FIPS
523    // Not allowed
524    //
525    /// # Errors
526    /// `error::Unspecified` if the signature is invalid or verification fails.
527    #[inline]
528    pub fn verify_digest_sig(
529        &self,
530        digest: &Digest,
531        signature: &[u8],
532    ) -> Result<(), error::Unspecified> {
533        self.parsed_algorithm
534            .parsed_verify_digest_sig(self, digest, signature)
535    }
536}
537
538impl AsDer<PublicKeyX509Der<'static>> for ParsedPublicKey {
539    fn as_der(&self) -> Result<PublicKeyX509Der<'static>, Unspecified> {
540        Ok(PublicKeyX509Der::new(
541            self.key.as_const().marshal_rfc5280_public_key()?,
542        ))
543    }
544}
545
546/// Provides the original bytes from which this key was parsed
547impl AsRef<[u8]> for ParsedPublicKey {
548    fn as_ref(&self) -> &[u8] {
549        &self.bytes
550    }
551}
552
553impl Debug for ParsedPublicKey {
554    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
555        f.write_str(&format!(
556            "ParsedPublicKey {{ algorithm: {:?}, bytes: \"{}\" }}",
557            self.algorithm,
558            hex::encode(self.bytes.as_ref())
559        ))
560    }
561}
562
563impl<B: AsRef<[u8]>> AsRef<[u8]> for UnparsedPublicKey<B> {
564    #[inline]
565    fn as_ref(&self) -> &[u8] {
566        self.bytes.as_ref()
567    }
568}
569
570impl<B: Copy + AsRef<[u8]>> Copy for UnparsedPublicKey<B> {}
571
572impl<B: AsRef<[u8]>> Debug for UnparsedPublicKey<B> {
573    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
574        f.write_str(&format!(
575            "UnparsedPublicKey {{ algorithm: {:?}, bytes: \"{}\" }}",
576            self.algorithm,
577            hex::encode(self.bytes.as_ref())
578        ))
579    }
580}
581
582impl<B: AsRef<[u8]>> UnparsedPublicKey<B> {
583    /// Construct a new `UnparsedPublicKey`.
584    ///
585    /// No validation of `bytes` is done until `verify()` is called.
586    #[inline]
587    pub fn new(algorithm: &'static dyn VerificationAlgorithm, bytes: B) -> Self {
588        Self { algorithm, bytes }
589    }
590
591    /// Parses the public key and verifies `signature` is a valid signature of
592    /// `message` using it.
593    ///
594    /// See the [`crate::signature`] module-level documentation for examples.
595    ///
596    // # FIPS
597    // The following conditions must be met:
598    // * RSA Key Sizes: 1024, 2048, 3072, 4096
599    // * NIST Elliptic Curves: P256, P384, P521
600    // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
601    //
602    /// # Errors
603    /// `error::Unspecified` if inputs not verified.
604    #[inline]
605    pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified> {
606        self.algorithm
607            .verify_sig(self.bytes.as_ref(), message, signature)
608    }
609
610    /// Parses the public key and verifies `signature` is a valid signature of
611    /// `digest` using it.
612    ///
613    /// See the [`crate::signature`] module-level documentation for examples.
614    ///
615    // # FIPS
616    // Not allowed
617    //
618    /// # Errors
619    /// `error::Unspecified` if inputs not verified.
620    #[inline]
621    pub fn verify_digest(
622        &self,
623        digest: &Digest,
624        signature: &[u8],
625    ) -> Result<(), error::Unspecified> {
626        self.algorithm
627            .verify_digest_sig(self.bytes.as_ref(), digest, signature)
628    }
629
630    /// Parses the public key bytes and returns a `ParsedPublicKey`.
631    ///
632    /// This method validates the public key format and creates a `ParsedPublicKey`
633    /// that can be used for more efficient signature verification operations.
634    /// The parsing overhead is incurred once, making subsequent verifications
635    /// faster compared to using `UnparsedPublicKey::verify` directly.
636    ///
637    /// This is equivalent to calling [`ParsedPublicKey::new`] with the same
638    /// algorithm and bytes.
639    ///
640    /// # Errors
641    /// `KeyRejected` if the public key bytes are malformed or incompatible
642    /// with the specified algorithm.
643    pub fn parse(&self) -> Result<ParsedPublicKey, KeyRejected> {
644        parse_public_key(self.bytes.as_ref(), self.algorithm)
645    }
646}
647
648pub(crate) fn parse_public_key(
649    bytes: &[u8],
650    algorithm: &'static dyn VerificationAlgorithm,
651) -> Result<ParsedPublicKey, KeyRejected> {
652    let parsed_algorithm: &'static dyn ParsedVerificationAlgorithm;
653
654    let key = if algorithm.type_id() == TypeId::of::<EcdsaVerificationAlgorithm>() {
655        #[allow(clippy::cast_ptr_alignment)]
656        let ec_alg = unsafe {
657            &*(algorithm as *const dyn VerificationAlgorithm).cast::<EcdsaVerificationAlgorithm>()
658        };
659        parsed_algorithm = ec_alg;
660        parse_ec_public_key(bytes, ec_alg.id.nid())?
661    } else if algorithm.type_id() == TypeId::of::<EdDSAParameters>() {
662        #[allow(clippy::cast_ptr_alignment)]
663        let ed_alg =
664            unsafe { &*(algorithm as *const dyn VerificationAlgorithm).cast::<EdDSAParameters>() };
665        parsed_algorithm = ed_alg;
666        parse_ed25519_public_key(bytes)?
667    } else if algorithm.type_id() == TypeId::of::<RsaParameters>() {
668        #[allow(clippy::cast_ptr_alignment)]
669        let rsa_alg =
670            unsafe { &*(algorithm as *const dyn VerificationAlgorithm).cast::<RsaParameters>() };
671        parsed_algorithm = rsa_alg;
672        parse_rsa_public_key(bytes)?
673    } else {
674        #[cfg(all(feature = "unstable", not(feature = "fips")))]
675        if algorithm.type_id() == TypeId::of::<PqdsaVerificationAlgorithm>() {
676            #[allow(clippy::cast_ptr_alignment)]
677            let pqdsa_alg = unsafe {
678                &*(algorithm as *const dyn VerificationAlgorithm)
679                    .cast::<PqdsaVerificationAlgorithm>()
680            };
681            parsed_algorithm = pqdsa_alg;
682            parse_pqdsa_public_key(bytes, pqdsa_alg.id)?
683        } else {
684            unreachable!()
685        }
686        #[cfg(any(not(feature = "unstable"), feature = "fips"))]
687        unreachable!()
688    };
689
690    let bytes = bytes.to_vec().into_boxed_slice();
691    Ok(ParsedPublicKey {
692        algorithm,
693        parsed_algorithm,
694        key,
695        bytes,
696    })
697}
698
699/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-1.
700pub const RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
701    &digest::SHA1_FOR_LEGACY_USE_ONLY,
702    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
703    1024..=8192,
704    &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
705);
706
707/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-256.
708pub const RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
709    &digest::SHA256,
710    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
711    1024..=8192,
712    &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY,
713);
714
715/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-512.
716pub const RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
717    &digest::SHA512,
718    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
719    1024..=8192,
720    &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY,
721);
722
723/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-1.
724pub const RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
725    &digest::SHA1_FOR_LEGACY_USE_ONLY,
726    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
727    2048..=8192,
728    &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY,
729);
730
731/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-256.
732pub const RSA_PKCS1_2048_8192_SHA256: RsaParameters = RsaParameters::new(
733    &digest::SHA256,
734    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
735    2048..=8192,
736    &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA256,
737);
738
739/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-384.
740pub const RSA_PKCS1_2048_8192_SHA384: RsaParameters = RsaParameters::new(
741    &digest::SHA384,
742    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
743    2048..=8192,
744    &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA384,
745);
746
747/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-512.
748pub const RSA_PKCS1_2048_8192_SHA512: RsaParameters = RsaParameters::new(
749    &digest::SHA512,
750    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
751    2048..=8192,
752    &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA512,
753);
754
755/// Verification of signatures using RSA keys of 3072-8192 bits, PKCS#1.5 padding, and SHA-384.
756pub const RSA_PKCS1_3072_8192_SHA384: RsaParameters = RsaParameters::new(
757    &digest::SHA384,
758    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
759    3072..=8192,
760    &RsaVerificationAlgorithmId::RSA_PKCS1_3072_8192_SHA384,
761);
762
763/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-256.
764pub const RSA_PSS_2048_8192_SHA256: RsaParameters = RsaParameters::new(
765    &digest::SHA256,
766    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
767    2048..=8192,
768    &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA256,
769);
770
771/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-384.
772pub const RSA_PSS_2048_8192_SHA384: RsaParameters = RsaParameters::new(
773    &digest::SHA384,
774    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
775    2048..=8192,
776    &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA384,
777);
778
779/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-512.
780pub const RSA_PSS_2048_8192_SHA512: RsaParameters = RsaParameters::new(
781    &digest::SHA512,
782    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
783    2048..=8192,
784    &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA512,
785);
786
787/// RSA PSS padding using SHA-256 for RSA signatures.
788pub const RSA_PSS_SHA256: RsaSignatureEncoding = RsaSignatureEncoding::new(
789    &digest::SHA256,
790    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
791    &RsaSigningAlgorithmId::RSA_PSS_SHA256,
792);
793
794/// RSA PSS padding using SHA-384 for RSA signatures.
795pub const RSA_PSS_SHA384: RsaSignatureEncoding = RsaSignatureEncoding::new(
796    &digest::SHA384,
797    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
798    &RsaSigningAlgorithmId::RSA_PSS_SHA384,
799);
800
801/// RSA PSS padding using SHA-512 for RSA signatures.
802pub const RSA_PSS_SHA512: RsaSignatureEncoding = RsaSignatureEncoding::new(
803    &digest::SHA512,
804    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
805    &RsaSigningAlgorithmId::RSA_PSS_SHA512,
806);
807
808/// PKCS#1 1.5 padding using SHA-256 for RSA signatures.
809pub const RSA_PKCS1_SHA256: RsaSignatureEncoding = RsaSignatureEncoding::new(
810    &digest::SHA256,
811    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
812    &RsaSigningAlgorithmId::RSA_PKCS1_SHA256,
813);
814
815/// PKCS#1 1.5 padding using SHA-384 for RSA signatures.
816pub const RSA_PKCS1_SHA384: RsaSignatureEncoding = RsaSignatureEncoding::new(
817    &digest::SHA384,
818    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
819    &RsaSigningAlgorithmId::RSA_PKCS1_SHA384,
820);
821
822/// PKCS#1 1.5 padding using SHA-512 for RSA signatures.
823pub const RSA_PKCS1_SHA512: RsaSignatureEncoding = RsaSignatureEncoding::new(
824    &digest::SHA512,
825    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
826    &RsaSigningAlgorithmId::RSA_PKCS1_SHA512,
827);
828
829/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256 curve and SHA-256.
830pub const ECDSA_P256_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
831    id: &ec::signature::AlgorithmID::ECDSA_P256,
832    digest: &digest::SHA256,
833    sig_format: EcdsaSignatureFormat::Fixed,
834};
835
836/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA-384.
837pub const ECDSA_P384_SHA384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
838    id: &ec::signature::AlgorithmID::ECDSA_P384,
839    digest: &digest::SHA384,
840    sig_format: EcdsaSignatureFormat::Fixed,
841};
842
843/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA3-384.
844pub const ECDSA_P384_SHA3_384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
845    id: &ec::signature::AlgorithmID::ECDSA_P384,
846    digest: &digest::SHA3_384,
847    sig_format: EcdsaSignatureFormat::Fixed,
848};
849
850/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-1.
851pub const ECDSA_P521_SHA1_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
852    id: &ec::signature::AlgorithmID::ECDSA_P521,
853    digest: &digest::SHA1_FOR_LEGACY_USE_ONLY,
854    sig_format: EcdsaSignatureFormat::Fixed,
855};
856
857/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-224.
858pub const ECDSA_P521_SHA224_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
859    id: &ec::signature::AlgorithmID::ECDSA_P521,
860    digest: &digest::SHA224,
861    sig_format: EcdsaSignatureFormat::Fixed,
862};
863
864/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-256.
865pub const ECDSA_P521_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
866    id: &ec::signature::AlgorithmID::ECDSA_P521,
867    digest: &digest::SHA256,
868    sig_format: EcdsaSignatureFormat::Fixed,
869};
870
871/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-384.
872pub const ECDSA_P521_SHA384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
873    id: &ec::signature::AlgorithmID::ECDSA_P521,
874    digest: &digest::SHA384,
875    sig_format: EcdsaSignatureFormat::Fixed,
876};
877
878/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-512.
879pub const ECDSA_P521_SHA512_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
880    id: &ec::signature::AlgorithmID::ECDSA_P521,
881    digest: &digest::SHA512,
882    sig_format: EcdsaSignatureFormat::Fixed,
883};
884
885/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA3-512.
886pub const ECDSA_P521_SHA3_512_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
887    id: &ec::signature::AlgorithmID::ECDSA_P521,
888    digest: &digest::SHA3_512,
889    sig_format: EcdsaSignatureFormat::Fixed,
890};
891
892/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA-256.
893pub const ECDSA_P256K1_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
894    id: &ec::signature::AlgorithmID::ECDSA_P256K1,
895    digest: &digest::SHA256,
896    sig_format: EcdsaSignatureFormat::Fixed,
897};
898
899/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA3-256.
900pub const ECDSA_P256K1_SHA3_256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
901    id: &ec::signature::AlgorithmID::ECDSA_P256K1,
902    digest: &digest::SHA3_256,
903    sig_format: EcdsaSignatureFormat::Fixed,
904};
905
906/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-256.
907pub const ECDSA_P256_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
908    id: &ec::signature::AlgorithmID::ECDSA_P256,
909    digest: &digest::SHA256,
910    sig_format: EcdsaSignatureFormat::ASN1,
911};
912
913/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-384.
914pub const ECDSA_P256_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
915    id: &ec::signature::AlgorithmID::ECDSA_P256,
916    digest: &digest::SHA384,
917    sig_format: EcdsaSignatureFormat::ASN1,
918};
919
920/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-512.
921pub const ECDSA_P256_SHA512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
922    id: &ec::signature::AlgorithmID::ECDSA_P256,
923    digest: &digest::SHA512,
924    sig_format: EcdsaSignatureFormat::ASN1,
925};
926
927/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-256.
928pub const ECDSA_P384_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
929    id: &ec::signature::AlgorithmID::ECDSA_P384,
930    digest: &digest::SHA256,
931    sig_format: EcdsaSignatureFormat::ASN1,
932};
933
934/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-384.
935pub const ECDSA_P384_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
936    id: &ec::signature::AlgorithmID::ECDSA_P384,
937    digest: &digest::SHA384,
938    sig_format: EcdsaSignatureFormat::ASN1,
939};
940
941/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-512.
942pub const ECDSA_P384_SHA512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
943    id: &ec::signature::AlgorithmID::ECDSA_P384,
944    digest: &digest::SHA512,
945    sig_format: EcdsaSignatureFormat::ASN1,
946};
947
948/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA3-384.
949pub const ECDSA_P384_SHA3_384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
950    id: &ec::signature::AlgorithmID::ECDSA_P384,
951    digest: &digest::SHA3_384,
952    sig_format: EcdsaSignatureFormat::ASN1,
953};
954
955/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-1.
956pub const ECDSA_P521_SHA1_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
957    id: &ec::signature::AlgorithmID::ECDSA_P521,
958    digest: &digest::SHA1_FOR_LEGACY_USE_ONLY,
959    sig_format: EcdsaSignatureFormat::ASN1,
960};
961
962/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-224.
963pub const ECDSA_P521_SHA224_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
964    id: &ec::signature::AlgorithmID::ECDSA_P521,
965    digest: &digest::SHA224,
966    sig_format: EcdsaSignatureFormat::ASN1,
967};
968
969/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-256.
970pub const ECDSA_P521_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
971    id: &ec::signature::AlgorithmID::ECDSA_P521,
972    digest: &digest::SHA256,
973    sig_format: EcdsaSignatureFormat::ASN1,
974};
975
976/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-384.
977pub const ECDSA_P521_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
978    id: &ec::signature::AlgorithmID::ECDSA_P521,
979    digest: &digest::SHA384,
980    sig_format: EcdsaSignatureFormat::ASN1,
981};
982
983/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-512.
984pub const ECDSA_P521_SHA512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
985    id: &ec::signature::AlgorithmID::ECDSA_P521,
986    digest: &digest::SHA512,
987    sig_format: EcdsaSignatureFormat::ASN1,
988};
989
990/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA3-512.
991pub const ECDSA_P521_SHA3_512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
992    id: &ec::signature::AlgorithmID::ECDSA_P521,
993    digest: &digest::SHA3_512,
994    sig_format: EcdsaSignatureFormat::ASN1,
995};
996
997/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA-256.
998pub const ECDSA_P256K1_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
999    id: &ec::signature::AlgorithmID::ECDSA_P256K1,
1000    digest: &digest::SHA256,
1001    sig_format: EcdsaSignatureFormat::ASN1,
1002};
1003
1004/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA3-256.
1005pub const ECDSA_P256K1_SHA3_256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1006    id: &ec::signature::AlgorithmID::ECDSA_P256K1,
1007    digest: &digest::SHA3_256,
1008    sig_format: EcdsaSignatureFormat::ASN1,
1009};
1010
1011/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256 curve and SHA-256.
1012pub const ECDSA_P256_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1013    EcdsaSigningAlgorithm(&ECDSA_P256_SHA256_FIXED);
1014
1015/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA-384.
1016pub const ECDSA_P384_SHA384_FIXED_SIGNING: EcdsaSigningAlgorithm =
1017    EcdsaSigningAlgorithm(&ECDSA_P384_SHA384_FIXED);
1018
1019/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA3-384.
1020pub const ECDSA_P384_SHA3_384_FIXED_SIGNING: EcdsaSigningAlgorithm =
1021    EcdsaSigningAlgorithm(&ECDSA_P384_SHA3_384_FIXED);
1022
1023/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-224.
1024/// # ⚠️ Warning
1025/// The security design strength of SHA-224 digests is less then security strength of P-521.
1026/// This scheme should only be used for backwards compatibility purposes.
1027pub const ECDSA_P521_SHA224_FIXED_SIGNING: EcdsaSigningAlgorithm =
1028    EcdsaSigningAlgorithm(&ECDSA_P521_SHA224_FIXED);
1029
1030/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-256.
1031/// # ⚠️ Warning
1032/// The security design strength of SHA-256 digests is less then security strength of P-521.
1033/// This scheme should only be used for backwards compatibility purposes.
1034pub const ECDSA_P521_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1035    EcdsaSigningAlgorithm(&ECDSA_P521_SHA256_FIXED);
1036
1037/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-384.
1038/// # ⚠️ Warning
1039/// The security design strength of SHA-384 digests is less then security strength of P-521.
1040/// This scheme should only be used for backwards compatibility purposes.
1041pub const ECDSA_P521_SHA384_FIXED_SIGNING: EcdsaSigningAlgorithm =
1042    EcdsaSigningAlgorithm(&ECDSA_P521_SHA384_FIXED);
1043
1044/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-512.
1045pub const ECDSA_P521_SHA512_FIXED_SIGNING: EcdsaSigningAlgorithm =
1046    EcdsaSigningAlgorithm(&ECDSA_P521_SHA512_FIXED);
1047
1048/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA3-512.
1049pub const ECDSA_P521_SHA3_512_FIXED_SIGNING: EcdsaSigningAlgorithm =
1050    EcdsaSigningAlgorithm(&ECDSA_P521_SHA3_512_FIXED);
1051
1052/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA-256.
1053pub const ECDSA_P256K1_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1054    EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA256_FIXED);
1055
1056/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA3-256.
1057pub const ECDSA_P256K1_SHA3_256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1058    EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA3_256_FIXED);
1059
1060/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-256.
1061pub const ECDSA_P256_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1062    EcdsaSigningAlgorithm(&ECDSA_P256_SHA256_ASN1);
1063
1064/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-384.
1065pub const ECDSA_P384_SHA384_ASN1_SIGNING: EcdsaSigningAlgorithm =
1066    EcdsaSigningAlgorithm(&ECDSA_P384_SHA384_ASN1);
1067
1068/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA3-384.
1069pub const ECDSA_P384_SHA3_384_ASN1_SIGNING: EcdsaSigningAlgorithm =
1070    EcdsaSigningAlgorithm(&ECDSA_P384_SHA3_384_ASN1);
1071
1072/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-224.
1073/// # ⚠️ Warning
1074/// The security design strength of SHA-224 digests is less then security strength of P-521.
1075/// This scheme should only be used for backwards compatibility purposes.
1076pub const ECDSA_P521_SHA224_ASN1_SIGNING: EcdsaSigningAlgorithm =
1077    EcdsaSigningAlgorithm(&ECDSA_P521_SHA224_ASN1);
1078
1079/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-256.
1080/// # ⚠️ Warning
1081/// The security design strength of SHA-256 digests is less then security strength of P-521.
1082/// This scheme should only be used for backwards compatibility purposes.
1083pub const ECDSA_P521_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1084    EcdsaSigningAlgorithm(&ECDSA_P521_SHA256_ASN1);
1085
1086/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-384.
1087/// # ⚠️ Warning
1088/// The security design strength of SHA-384 digests is less then security strength of P-521.
1089/// This scheme should only be used for backwards compatibility purposes.
1090pub const ECDSA_P521_SHA384_ASN1_SIGNING: EcdsaSigningAlgorithm =
1091    EcdsaSigningAlgorithm(&ECDSA_P521_SHA384_ASN1);
1092
1093/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-512.
1094pub const ECDSA_P521_SHA512_ASN1_SIGNING: EcdsaSigningAlgorithm =
1095    EcdsaSigningAlgorithm(&ECDSA_P521_SHA512_ASN1);
1096
1097/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA3-512.
1098pub const ECDSA_P521_SHA3_512_ASN1_SIGNING: EcdsaSigningAlgorithm =
1099    EcdsaSigningAlgorithm(&ECDSA_P521_SHA3_512_ASN1);
1100
1101/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA-256.
1102pub const ECDSA_P256K1_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1103    EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA256_ASN1);
1104
1105/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA3-256.
1106pub const ECDSA_P256K1_SHA3_256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1107    EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA3_256_ASN1);
1108
1109/// Verification of Ed25519 signatures.
1110pub const ED25519: EdDSAParameters = EdDSAParameters {};
1111
1112#[cfg(test)]
1113mod tests {
1114    use crate::rand::{generate, SystemRandom};
1115    use crate::signature::{ParsedPublicKey, UnparsedPublicKey, ED25519};
1116    use crate::test;
1117    use regex::Regex;
1118
1119    #[cfg(feature = "fips")]
1120    mod fips;
1121
1122    #[test]
1123    fn test_unparsed_public_key() {
1124        let random_pubkey: [u8; 32] = generate(&SystemRandom::new()).unwrap().expose();
1125        let unparsed_pubkey = UnparsedPublicKey::new(&ED25519, random_pubkey);
1126        let unparsed_pubkey_debug = format!("{unparsed_pubkey:?}");
1127
1128        #[allow(clippy::clone_on_copy)]
1129        let unparsed_pubkey_clone = unparsed_pubkey.clone();
1130        assert_eq!(unparsed_pubkey_debug, format!("{unparsed_pubkey_clone:?}"));
1131        let pubkey_re = Regex::new(
1132            "UnparsedPublicKey \\{ algorithm: EdDSAParameters, bytes: \"[0-9a-f]{64}\" \\}",
1133        )
1134        .unwrap();
1135
1136        assert!(pubkey_re.is_match(&unparsed_pubkey_debug));
1137    }
1138    #[test]
1139    fn test_types() {
1140        test::compile_time_assert_send::<UnparsedPublicKey<&[u8]>>();
1141        test::compile_time_assert_sync::<UnparsedPublicKey<&[u8]>>();
1142        test::compile_time_assert_send::<UnparsedPublicKey<Vec<u8>>>();
1143        test::compile_time_assert_sync::<UnparsedPublicKey<Vec<u8>>>();
1144        test::compile_time_assert_clone::<UnparsedPublicKey<&[u8]>>();
1145        test::compile_time_assert_clone::<UnparsedPublicKey<Vec<u8>>>();
1146        test::compile_time_assert_send::<ParsedPublicKey>();
1147        test::compile_time_assert_sync::<ParsedPublicKey>();
1148        test::compile_time_assert_clone::<ParsedPublicKey>();
1149    }
1150}