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 core::fmt::{Debug, Formatter};
237
238#[cfg(feature = "ring-sig-verify")]
239use untrusted::Input;
240
241pub use crate::rsa::signature::RsaEncoding;
242pub use crate::rsa::{
243 KeyPair as RsaKeyPair, PublicKey as RsaSubjectPublicKey,
244 PublicKeyComponents as RsaPublicKeyComponents, RsaParameters,
245};
246
247use crate::rsa::signature::{RsaSignatureEncoding, 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, ec, error, hex, rsa, sealed};
261
262/// The longest signature is for ML-DSA-87
263pub(crate) const MAX_LEN: usize = 4627;
264
265/// A public key signature returned from a signing operation.
266#[derive(Clone, Copy)]
267pub struct Signature {
268 value: [u8; MAX_LEN],
269 len: usize,
270}
271
272impl Signature {
273 // Panics if `value` is too long.
274 pub(crate) fn new<F>(fill: F) -> Self
275 where
276 F: FnOnce(&mut [u8; MAX_LEN]) -> usize,
277 {
278 let mut r = Self {
279 value: [0; MAX_LEN],
280 len: 0,
281 };
282 r.len = fill(&mut r.value);
283 r
284 }
285}
286
287impl AsRef<[u8]> for Signature {
288 #[inline]
289 fn as_ref(&self) -> &[u8] {
290 &self.value[..self.len]
291 }
292}
293
294/// Key pairs for signing messages (private key and public key).
295pub trait KeyPair: Debug + Send + Sized + Sync {
296 /// The type of the public key.
297 type PublicKey: AsRef<[u8]> + Debug + Clone + Send + Sized + Sync;
298
299 /// The public key for the key pair.
300 fn public_key(&self) -> &Self::PublicKey;
301}
302
303/// A signature verification algorithm.
304pub trait VerificationAlgorithm: Debug + Sync + sealed::Sealed {
305 /// Verify the signature `signature` of message `msg` with the public key
306 /// `public_key`.
307 ///
308 // # FIPS
309 // The following conditions must be met:
310 // * RSA Key Sizes: 1024, 2048, 3072, 4096
311 // * NIST Elliptic Curves: P256, P384, P521
312 // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
313 //
314 /// # Errors
315 /// `error::Unspecified` if inputs not verified.
316 #[cfg(feature = "ring-sig-verify")]
317 #[deprecated(note = "please use `VerificationAlgorithm::verify_sig` instead")]
318 fn verify(
319 &self,
320 public_key: Input<'_>,
321 msg: Input<'_>,
322 signature: Input<'_>,
323 ) -> Result<(), error::Unspecified>;
324
325 /// Verify the signature `signature` of message `msg` with the public key
326 /// `public_key`.
327 ///
328 // # FIPS
329 // The following conditions must be met:
330 // * RSA Key Sizes: 1024, 2048, 3072, 4096
331 // * NIST Elliptic Curves: P256, P384, P521
332 // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
333 //
334 /// # Errors
335 /// `error::Unspecified` if inputs not verified.
336 fn verify_sig(
337 &self,
338 public_key: &[u8],
339 msg: &[u8],
340 signature: &[u8],
341 ) -> Result<(), error::Unspecified>;
342}
343
344/// An unparsed, possibly malformed, public key for signature verification.
345#[derive(Clone)]
346pub struct UnparsedPublicKey<B: AsRef<[u8]>> {
347 algorithm: &'static dyn VerificationAlgorithm,
348 bytes: B,
349}
350
351impl<B: Copy + AsRef<[u8]>> Copy for UnparsedPublicKey<B> {}
352
353impl<B: AsRef<[u8]>> Debug for UnparsedPublicKey<B> {
354 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
355 f.write_str(&format!(
356 "UnparsedPublicKey {{ algorithm: {:?}, bytes: \"{}\" }}",
357 self.algorithm,
358 hex::encode(self.bytes.as_ref())
359 ))
360 }
361}
362
363impl<B: AsRef<[u8]>> AsRef<[u8]> for UnparsedPublicKey<B> {
364 #[inline]
365 fn as_ref(&self) -> &[u8] {
366 self.bytes.as_ref()
367 }
368}
369
370impl<B: AsRef<[u8]>> UnparsedPublicKey<B> {
371 /// Construct a new `UnparsedPublicKey`.
372 ///
373 /// No validation of `bytes` is done until `verify()` is called.
374 #[inline]
375 pub fn new(algorithm: &'static dyn VerificationAlgorithm, bytes: B) -> Self {
376 Self { algorithm, bytes }
377 }
378
379 /// Parses the public key and verifies `signature` is a valid signature of
380 /// `message` using it.
381 ///
382 /// See the [`crate::signature`] module-level documentation for examples.
383 ///
384 // # FIPS
385 // The following conditions must be met:
386 // * RSA Key Sizes: 1024, 2048, 3072, 4096
387 // * NIST Elliptic Curves: P256, P384, P521
388 // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
389 //
390 /// # Errors
391 /// `error::Unspecified` if inputs not verified.
392 #[inline]
393 pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified> {
394 self.algorithm
395 .verify_sig(self.bytes.as_ref(), message, signature)
396 }
397}
398
399/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-1.
400pub static RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
401 &digest::SHA1_FOR_LEGACY_USE_ONLY,
402 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
403 1024..=8192,
404 &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
405);
406
407/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-256.
408pub static RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
409 &digest::SHA256,
410 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
411 1024..=8192,
412 &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY,
413);
414
415/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-512.
416pub static RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
417 &digest::SHA512,
418 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
419 1024..=8192,
420 &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY,
421);
422
423/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-1.
424pub static RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
425 &digest::SHA1_FOR_LEGACY_USE_ONLY,
426 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
427 2048..=8192,
428 &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY,
429);
430
431/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-256.
432pub static RSA_PKCS1_2048_8192_SHA256: RsaParameters = RsaParameters::new(
433 &digest::SHA256,
434 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
435 2048..=8192,
436 &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA256,
437);
438
439/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-384.
440pub static RSA_PKCS1_2048_8192_SHA384: RsaParameters = RsaParameters::new(
441 &digest::SHA384,
442 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
443 2048..=8192,
444 &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA384,
445);
446
447/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-512.
448pub static RSA_PKCS1_2048_8192_SHA512: RsaParameters = RsaParameters::new(
449 &digest::SHA512,
450 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
451 2048..=8192,
452 &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA512,
453);
454
455/// Verification of signatures using RSA keys of 3072-8192 bits, PKCS#1.5 padding, and SHA-384.
456pub static RSA_PKCS1_3072_8192_SHA384: RsaParameters = RsaParameters::new(
457 &digest::SHA384,
458 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
459 3072..=8192,
460 &RsaVerificationAlgorithmId::RSA_PKCS1_3072_8192_SHA384,
461);
462
463/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-256.
464pub static RSA_PSS_2048_8192_SHA256: RsaParameters = RsaParameters::new(
465 &digest::SHA256,
466 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
467 2048..=8192,
468 &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA256,
469);
470
471/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-384.
472pub static RSA_PSS_2048_8192_SHA384: RsaParameters = RsaParameters::new(
473 &digest::SHA384,
474 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
475 2048..=8192,
476 &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA384,
477);
478
479/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-512.
480pub static RSA_PSS_2048_8192_SHA512: RsaParameters = RsaParameters::new(
481 &digest::SHA512,
482 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
483 2048..=8192,
484 &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA512,
485);
486
487/// RSA PSS padding using SHA-256 for RSA signatures.
488pub static RSA_PSS_SHA256: RsaSignatureEncoding = RsaSignatureEncoding::new(
489 &digest::SHA256,
490 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
491 &RsaSigningAlgorithmId::RSA_PSS_SHA256,
492);
493
494/// RSA PSS padding using SHA-384 for RSA signatures.
495pub static RSA_PSS_SHA384: RsaSignatureEncoding = RsaSignatureEncoding::new(
496 &digest::SHA384,
497 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
498 &RsaSigningAlgorithmId::RSA_PSS_SHA384,
499);
500
501/// RSA PSS padding using SHA-512 for RSA signatures.
502pub static RSA_PSS_SHA512: RsaSignatureEncoding = RsaSignatureEncoding::new(
503 &digest::SHA512,
504 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
505 &RsaSigningAlgorithmId::RSA_PSS_SHA512,
506);
507
508/// PKCS#1 1.5 padding using SHA-256 for RSA signatures.
509pub static RSA_PKCS1_SHA256: RsaSignatureEncoding = RsaSignatureEncoding::new(
510 &digest::SHA256,
511 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
512 &RsaSigningAlgorithmId::RSA_PKCS1_SHA256,
513);
514
515/// PKCS#1 1.5 padding using SHA-384 for RSA signatures.
516pub static RSA_PKCS1_SHA384: RsaSignatureEncoding = RsaSignatureEncoding::new(
517 &digest::SHA384,
518 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
519 &RsaSigningAlgorithmId::RSA_PKCS1_SHA384,
520);
521
522/// PKCS#1 1.5 padding using SHA-512 for RSA signatures.
523pub static RSA_PKCS1_SHA512: RsaSignatureEncoding = RsaSignatureEncoding::new(
524 &digest::SHA512,
525 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
526 &RsaSigningAlgorithmId::RSA_PKCS1_SHA512,
527);
528
529/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256 curve and SHA-256.
530pub static ECDSA_P256_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
531 id: &ec::signature::AlgorithmID::ECDSA_P256,
532 digest: &digest::SHA256,
533 sig_format: EcdsaSignatureFormat::Fixed,
534};
535
536/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA-384.
537pub static ECDSA_P384_SHA384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
538 id: &ec::signature::AlgorithmID::ECDSA_P384,
539 digest: &digest::SHA384,
540 sig_format: EcdsaSignatureFormat::Fixed,
541};
542
543/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA3-384.
544pub static ECDSA_P384_SHA3_384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
545 id: &ec::signature::AlgorithmID::ECDSA_P384,
546 digest: &digest::SHA3_384,
547 sig_format: EcdsaSignatureFormat::Fixed,
548};
549
550/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-1.
551pub static ECDSA_P521_SHA1_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
552 id: &ec::signature::AlgorithmID::ECDSA_P521,
553 digest: &digest::SHA1_FOR_LEGACY_USE_ONLY,
554 sig_format: EcdsaSignatureFormat::Fixed,
555};
556
557/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-224.
558pub static ECDSA_P521_SHA224_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
559 id: &ec::signature::AlgorithmID::ECDSA_P521,
560 digest: &digest::SHA224,
561 sig_format: EcdsaSignatureFormat::Fixed,
562};
563
564/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-256.
565pub static ECDSA_P521_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
566 id: &ec::signature::AlgorithmID::ECDSA_P521,
567 digest: &digest::SHA256,
568 sig_format: EcdsaSignatureFormat::Fixed,
569};
570
571/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-384.
572pub static ECDSA_P521_SHA384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
573 id: &ec::signature::AlgorithmID::ECDSA_P521,
574 digest: &digest::SHA384,
575 sig_format: EcdsaSignatureFormat::Fixed,
576};
577
578/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-512.
579pub static ECDSA_P521_SHA512_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
580 id: &ec::signature::AlgorithmID::ECDSA_P521,
581 digest: &digest::SHA512,
582 sig_format: EcdsaSignatureFormat::Fixed,
583};
584
585/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA3-512.
586pub static ECDSA_P521_SHA3_512_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
587 id: &ec::signature::AlgorithmID::ECDSA_P521,
588 digest: &digest::SHA3_512,
589 sig_format: EcdsaSignatureFormat::Fixed,
590};
591
592/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA-256.
593pub static ECDSA_P256K1_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
594 id: &ec::signature::AlgorithmID::ECDSA_P256K1,
595 digest: &digest::SHA256,
596 sig_format: EcdsaSignatureFormat::Fixed,
597};
598
599/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA3-256.
600pub static ECDSA_P256K1_SHA3_256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
601 id: &ec::signature::AlgorithmID::ECDSA_P256K1,
602 digest: &digest::SHA3_256,
603 sig_format: EcdsaSignatureFormat::Fixed,
604};
605
606/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-256.
607pub static ECDSA_P256_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
608 id: &ec::signature::AlgorithmID::ECDSA_P256,
609 digest: &digest::SHA256,
610 sig_format: EcdsaSignatureFormat::ASN1,
611};
612
613/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-384.
614pub static ECDSA_P256_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
615 id: &ec::signature::AlgorithmID::ECDSA_P256,
616 digest: &digest::SHA384,
617 sig_format: EcdsaSignatureFormat::ASN1,
618};
619
620/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-256.
621pub static ECDSA_P384_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
622 id: &ec::signature::AlgorithmID::ECDSA_P384,
623 digest: &digest::SHA256,
624 sig_format: EcdsaSignatureFormat::ASN1,
625};
626
627/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-384.
628pub static ECDSA_P384_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
629 id: &ec::signature::AlgorithmID::ECDSA_P384,
630 digest: &digest::SHA384,
631 sig_format: EcdsaSignatureFormat::ASN1,
632};
633
634/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA3-384.
635pub static ECDSA_P384_SHA3_384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
636 id: &ec::signature::AlgorithmID::ECDSA_P384,
637 digest: &digest::SHA3_384,
638 sig_format: EcdsaSignatureFormat::ASN1,
639};
640
641/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-1.
642pub static ECDSA_P521_SHA1_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
643 id: &ec::signature::AlgorithmID::ECDSA_P521,
644 digest: &digest::SHA1_FOR_LEGACY_USE_ONLY,
645 sig_format: EcdsaSignatureFormat::ASN1,
646};
647
648/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-224.
649pub static ECDSA_P521_SHA224_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
650 id: &ec::signature::AlgorithmID::ECDSA_P521,
651 digest: &digest::SHA224,
652 sig_format: EcdsaSignatureFormat::ASN1,
653};
654
655/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-256.
656pub static ECDSA_P521_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
657 id: &ec::signature::AlgorithmID::ECDSA_P521,
658 digest: &digest::SHA256,
659 sig_format: EcdsaSignatureFormat::ASN1,
660};
661
662/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-384.
663pub static ECDSA_P521_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
664 id: &ec::signature::AlgorithmID::ECDSA_P521,
665 digest: &digest::SHA384,
666 sig_format: EcdsaSignatureFormat::ASN1,
667};
668
669/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-512.
670pub static ECDSA_P521_SHA512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
671 id: &ec::signature::AlgorithmID::ECDSA_P521,
672 digest: &digest::SHA512,
673 sig_format: EcdsaSignatureFormat::ASN1,
674};
675
676/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA3-512.
677pub static ECDSA_P521_SHA3_512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
678 id: &ec::signature::AlgorithmID::ECDSA_P521,
679 digest: &digest::SHA3_512,
680 sig_format: EcdsaSignatureFormat::ASN1,
681};
682
683/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA-256.
684pub static ECDSA_P256K1_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
685 id: &ec::signature::AlgorithmID::ECDSA_P256K1,
686 digest: &digest::SHA256,
687 sig_format: EcdsaSignatureFormat::ASN1,
688};
689
690/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA3-256.
691pub static ECDSA_P256K1_SHA3_256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
692 id: &ec::signature::AlgorithmID::ECDSA_P256K1,
693 digest: &digest::SHA3_256,
694 sig_format: EcdsaSignatureFormat::ASN1,
695};
696
697/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256 curve and SHA-256.
698pub static ECDSA_P256_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
699 EcdsaSigningAlgorithm(&ECDSA_P256_SHA256_FIXED);
700
701/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA-384.
702pub static ECDSA_P384_SHA384_FIXED_SIGNING: EcdsaSigningAlgorithm =
703 EcdsaSigningAlgorithm(&ECDSA_P384_SHA384_FIXED);
704
705/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA3-384.
706pub static ECDSA_P384_SHA3_384_FIXED_SIGNING: EcdsaSigningAlgorithm =
707 EcdsaSigningAlgorithm(&ECDSA_P384_SHA3_384_FIXED);
708
709/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-224.
710/// # ⚠️ Warning
711/// The security design strength of SHA-224 digests is less then security strength of P-521.
712/// This scheme should only be used for backwards compatibility purposes.
713pub static ECDSA_P521_SHA224_FIXED_SIGNING: EcdsaSigningAlgorithm =
714 EcdsaSigningAlgorithm(&ECDSA_P521_SHA224_FIXED);
715
716/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-256.
717/// # ⚠️ Warning
718/// The security design strength of SHA-256 digests is less then security strength of P-521.
719/// This scheme should only be used for backwards compatibility purposes.
720pub static ECDSA_P521_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
721 EcdsaSigningAlgorithm(&ECDSA_P521_SHA256_FIXED);
722
723/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-384.
724/// # ⚠️ Warning
725/// The security design strength of SHA-384 digests is less then security strength of P-521.
726/// This scheme should only be used for backwards compatibility purposes.
727pub static ECDSA_P521_SHA384_FIXED_SIGNING: EcdsaSigningAlgorithm =
728 EcdsaSigningAlgorithm(&ECDSA_P521_SHA384_FIXED);
729
730/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-512.
731pub static ECDSA_P521_SHA512_FIXED_SIGNING: EcdsaSigningAlgorithm =
732 EcdsaSigningAlgorithm(&ECDSA_P521_SHA512_FIXED);
733
734/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA3-512.
735pub static ECDSA_P521_SHA3_512_FIXED_SIGNING: EcdsaSigningAlgorithm =
736 EcdsaSigningAlgorithm(&ECDSA_P521_SHA3_512_FIXED);
737
738/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA-256.
739pub static ECDSA_P256K1_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
740 EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA256_FIXED);
741
742/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA3-256.
743pub static ECDSA_P256K1_SHA3_256_FIXED_SIGNING: EcdsaSigningAlgorithm =
744 EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA3_256_FIXED);
745
746/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-256.
747pub static ECDSA_P256_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
748 EcdsaSigningAlgorithm(&ECDSA_P256_SHA256_ASN1);
749
750/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-384.
751pub static ECDSA_P384_SHA384_ASN1_SIGNING: EcdsaSigningAlgorithm =
752 EcdsaSigningAlgorithm(&ECDSA_P384_SHA384_ASN1);
753
754/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA3-384.
755pub static ECDSA_P384_SHA3_384_ASN1_SIGNING: EcdsaSigningAlgorithm =
756 EcdsaSigningAlgorithm(&ECDSA_P384_SHA3_384_ASN1);
757
758/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-224.
759/// # ⚠️ Warning
760/// The security design strength of SHA-224 digests is less then security strength of P-521.
761/// This scheme should only be used for backwards compatibility purposes.
762pub static ECDSA_P521_SHA224_ASN1_SIGNING: EcdsaSigningAlgorithm =
763 EcdsaSigningAlgorithm(&ECDSA_P521_SHA224_ASN1);
764
765/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-256.
766/// # ⚠️ Warning
767/// The security design strength of SHA-256 digests is less then security strength of P-521.
768/// This scheme should only be used for backwards compatibility purposes.
769pub static ECDSA_P521_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
770 EcdsaSigningAlgorithm(&ECDSA_P521_SHA256_ASN1);
771
772/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-384.
773/// # ⚠️ Warning
774/// The security design strength of SHA-384 digests is less then security strength of P-521.
775/// This scheme should only be used for backwards compatibility purposes.
776pub static ECDSA_P521_SHA384_ASN1_SIGNING: EcdsaSigningAlgorithm =
777 EcdsaSigningAlgorithm(&ECDSA_P521_SHA384_ASN1);
778
779/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-512.
780pub static ECDSA_P521_SHA512_ASN1_SIGNING: EcdsaSigningAlgorithm =
781 EcdsaSigningAlgorithm(&ECDSA_P521_SHA512_ASN1);
782
783/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA3-512.
784pub static ECDSA_P521_SHA3_512_ASN1_SIGNING: EcdsaSigningAlgorithm =
785 EcdsaSigningAlgorithm(&ECDSA_P521_SHA3_512_ASN1);
786
787/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA-256.
788pub static ECDSA_P256K1_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
789 EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA256_ASN1);
790
791/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA3-256.
792pub static ECDSA_P256K1_SHA3_256_ASN1_SIGNING: EcdsaSigningAlgorithm =
793 EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA3_256_ASN1);
794
795/// Verification of Ed25519 signatures.
796pub static ED25519: EdDSAParameters = EdDSAParameters {};
797
798#[cfg(test)]
799mod tests {
800 use regex::Regex;
801
802 use crate::rand::{generate, SystemRandom};
803 use crate::signature::{UnparsedPublicKey, ED25519};
804
805 #[cfg(feature = "fips")]
806 mod fips;
807
808 #[test]
809 fn test_unparsed_public_key() {
810 let random_pubkey: [u8; 32] = generate(&SystemRandom::new()).unwrap().expose();
811 let unparsed_pubkey = UnparsedPublicKey::new(&ED25519, random_pubkey);
812 let unparsed_pubkey_debug = format!("{:?}", &unparsed_pubkey);
813
814 #[allow(clippy::clone_on_copy)]
815 let unparsed_pubkey_clone = unparsed_pubkey.clone();
816 assert_eq!(unparsed_pubkey_debug, format!("{unparsed_pubkey_clone:?}"));
817 let pubkey_re = Regex::new(
818 "UnparsedPublicKey \\{ algorithm: EdDSAParameters, bytes: \"[0-9a-f]{64}\" \\}",
819 )
820 .unwrap();
821
822 assert!(pubkey_re.is_match(&unparsed_pubkey_debug));
823 }
824}