From 917b1ba1b3d5f183d14458ee5e41085482a36121 Mon Sep 17 00:00:00 2001 From: Shrey Amin Date: Sun, 21 Jul 2024 16:07:55 -0400 Subject: [PATCH] Add support for P-521 curve with SHA-256/SHA-384 digests (#272) --- Cargo.lock | 8 +- Cargo.toml | 2 +- src/aws_lc_rs_algs.rs | 16 ++++ src/lib.rs | 12 ++- tests/generate.py | 10 ++- tests/signatures.rs | 81 +++++++++++++++++- tests/signatures/ecdsa_p521.ee.der | Bin 592 -> 592 bytes ..._p521_sha256_detects_bad_signature.sig.bin | 3 + ...d_ecdsa_p521_sha256_good_signature.sig.bin | Bin 0 -> 139 bytes ..._p521_sha384_detects_bad_signature.sig.bin | Bin 0 -> 139 bytes ...d_ecdsa_p521_sha384_good_signature.sig.bin | 2 + ..._p521_sha512_detects_bad_signature.sig.bin | Bin 138 -> 139 bytes ...d_ecdsa_p521_sha512_good_signature.sig.bin | Bin 139 -> 138 bytes 13 files changed, 120 insertions(+), 14 deletions(-) create mode 100644 tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha256_detects_bad_signature.sig.bin create mode 100644 tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha256_good_signature.sig.bin create mode 100644 tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha384_detects_bad_signature.sig.bin create mode 100644 tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha384_good_signature.sig.bin diff --git a/Cargo.lock b/Cargo.lock index 97667c28..3079ed6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a47f2fb521b70c11ce7369a6c5fa4bd6af7e5d62ec06303875bafe7c6ba245" +checksum = "4ae74d9bd0a7530e8afd1770739ad34b36838829d6ad61818f9230f683f5ad77" dependencies = [ "aws-lc-sys", "mirai-annotations", @@ -26,9 +26,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2927c7af777b460b7ccd95f8b67acd7b4c04ec8896bf0c8e80ba30523cffc057" +checksum = "2e89b6941c2d1a7045538884d6e760ccfffdf8e1ffc2613d8efa74305e1f3752" dependencies = [ "bindgen", "cc", diff --git a/Cargo.toml b/Cargo.toml index 7b3f6f19..431371e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,7 +79,7 @@ ring = ["dep:ring"] std = ["alloc", "pki-types/std"] [dependencies] -aws-lc-rs = { version = "1", optional = true, default-features = false, features = ["aws-lc-sys"] } +aws-lc-rs = { version = "1.8.1", optional = true, default-features = false, features = ["aws-lc-sys"] } pki-types = { package = "rustls-pki-types", version = "1.7", default-features = false } ring = { version = "0.17", default-features = false, optional = true } untrusted = "0.9" diff --git a/src/aws_lc_rs_algs.rs b/src/aws_lc_rs_algs.rs index 2d2833f9..463a3dc5 100644 --- a/src/aws_lc_rs_algs.rs +++ b/src/aws_lc_rs_algs.rs @@ -67,6 +67,20 @@ pub static ECDSA_P384_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgo verification_alg: &signature::ECDSA_P384_SHA384_ASN1, }; +/// ECDSA signatures using the P-521 curve and SHA-256. +pub static ECDSA_P521_SHA256: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm { + public_key_alg_id: alg_id::ECDSA_P521, + signature_alg_id: alg_id::ECDSA_SHA256, + verification_alg: &signature::ECDSA_P521_SHA256_ASN1, +}; + +/// ECDSA signatures using the P-521 curve and SHA-384. +pub static ECDSA_P521_SHA384: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm { + public_key_alg_id: alg_id::ECDSA_P521, + signature_alg_id: alg_id::ECDSA_SHA384, + verification_alg: &signature::ECDSA_P521_SHA384_ASN1, +}; + /// ECDSA signatures using the P-521 curve and SHA-512. pub static ECDSA_P521_SHA512: &dyn SignatureVerificationAlgorithm = &AwsLcRsAlgorithm { public_key_alg_id: alg_id::ECDSA_P521, @@ -151,6 +165,8 @@ mod tests { // Reasonable algorithms. super::ECDSA_P256_SHA256, super::ECDSA_P384_SHA384, + super::ECDSA_P521_SHA256, + super::ECDSA_P521_SHA384, super::ECDSA_P521_SHA512, super::ED25519, super::RSA_PKCS1_2048_8192_SHA256, diff --git a/src/lib.rs b/src/lib.rs index a6546939..8c2ad54b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -109,10 +109,10 @@ pub mod ring { pub mod aws_lc_rs { pub use super::aws_lc_rs_algs::{ ECDSA_P256_SHA256, ECDSA_P256_SHA384, ECDSA_P384_SHA256, ECDSA_P384_SHA384, - ECDSA_P521_SHA512, ED25519, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_2048_8192_SHA384, - RSA_PKCS1_2048_8192_SHA512, RSA_PKCS1_3072_8192_SHA384, - RSA_PSS_2048_8192_SHA256_LEGACY_KEY, RSA_PSS_2048_8192_SHA384_LEGACY_KEY, - RSA_PSS_2048_8192_SHA512_LEGACY_KEY, + ECDSA_P521_SHA256, ECDSA_P521_SHA384, ECDSA_P521_SHA512, ED25519, + RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512, + RSA_PKCS1_3072_8192_SHA384, RSA_PSS_2048_8192_SHA256_LEGACY_KEY, + RSA_PSS_2048_8192_SHA384_LEGACY_KEY, RSA_PSS_2048_8192_SHA512_LEGACY_KEY, }; } @@ -153,6 +153,10 @@ pub static ALL_VERIFICATION_ALGS: &[&dyn types::SignatureVerificationAlgorithm] #[cfg(feature = "aws_lc_rs")] aws_lc_rs::ECDSA_P384_SHA384, #[cfg(feature = "aws_lc_rs")] + aws_lc_rs::ECDSA_P521_SHA256, + #[cfg(feature = "aws_lc_rs")] + aws_lc_rs::ECDSA_P521_SHA384, + #[cfg(feature = "aws_lc_rs")] aws_lc_rs::ECDSA_P521_SHA512, #[cfg(feature = "aws_lc_rs")] aws_lc_rs::ED25519, diff --git a/tests/generate.py b/tests/generate.py index 8ad626c0..c66b4c7f 100755 --- a/tests/generate.py +++ b/tests/generate.py @@ -560,6 +560,8 @@ def signatures(force: bool) -> None: } feature_gates = { + "ECDSA_P521_SHA256": 'all(not(feature = "ring"), feature = "aws_lc_rs")', + "ECDSA_P521_SHA384": 'all(not(feature = "ring"), feature = "aws_lc_rs")', "ECDSA_P521_SHA512": 'all(not(feature = "ring"), feature = "aws_lc_rs")', } @@ -576,7 +578,7 @@ def signatures(force: bool) -> None: "ed25519": ["ED25519"], "ecdsa_p256": ["ECDSA_P256_SHA384", "ECDSA_P256_SHA256"], "ecdsa_p384": ["ECDSA_P384_SHA384", "ECDSA_P384_SHA256"], - "ecdsa_p521": ["ECDSA_P521_SHA512"], + "ecdsa_p521": ["ECDSA_P521_SHA512", "ECDSA_P521_SHA256", "ECDSA_P521_SHA384"], "rsa_2048": rsa_types, "rsa_3072": rsa_types + ["RSA_PKCS1_3072_8192_SHA384"], "rsa_4096": rsa_types + ["RSA_PKCS1_3072_8192_SHA384"], @@ -606,6 +608,12 @@ def signatures(force: bool) -> None: "ECDSA_P384_SHA384": lambda key, message: key.sign( message, ec.ECDSA(hashes.SHA384()) ), + "ECDSA_P521_SHA256": lambda key, message: key.sign( + message, ec.ECDSA(hashes.SHA256()) + ), + "ECDSA_P521_SHA384": lambda key, message: key.sign( + message, ec.ECDSA(hashes.SHA384()) + ), "ECDSA_P521_SHA512": lambda key, message: key.sign( message, ec.ECDSA(hashes.SHA512()) ), diff --git a/tests/signatures.rs b/tests/signatures.rs index 9007d146..bd6e8a4d 100644 --- a/tests/signatures.rs +++ b/tests/signatures.rs @@ -28,10 +28,11 @@ use webpki::ring::{ #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] use webpki::aws_lc_rs::{ - ECDSA_P256_SHA256, ECDSA_P256_SHA384, ECDSA_P384_SHA256, ECDSA_P384_SHA384, ECDSA_P521_SHA512, - ED25519, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512, - RSA_PKCS1_3072_8192_SHA384, RSA_PSS_2048_8192_SHA256_LEGACY_KEY, - RSA_PSS_2048_8192_SHA384_LEGACY_KEY, RSA_PSS_2048_8192_SHA512_LEGACY_KEY, + ECDSA_P256_SHA256, ECDSA_P256_SHA384, ECDSA_P384_SHA256, ECDSA_P384_SHA384, ECDSA_P521_SHA256, + ECDSA_P521_SHA384, ECDSA_P521_SHA512, ED25519, RSA_PKCS1_2048_8192_SHA256, + RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512, RSA_PKCS1_3072_8192_SHA384, + RSA_PSS_2048_8192_SHA256_LEGACY_KEY, RSA_PSS_2048_8192_SHA384_LEGACY_KEY, + RSA_PSS_2048_8192_SHA512_LEGACY_KEY, }; #[cfg(feature = "alloc")] @@ -75,6 +76,10 @@ fn ed25519_key_and_ed25519_detects_bad_signature() { fn ed25519_key_rejected_by_other_algorithms() { let ee = include_bytes!("signatures/ed25519.ee.der"); for algorithm in &[ + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA256, + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA384, #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] ECDSA_P521_SHA512, ECDSA_P256_SHA256, @@ -149,6 +154,10 @@ fn ecdsa_p256_key_and_ecdsa_p256_sha256_detects_bad_signature() { fn ecdsa_p256_key_rejected_by_other_algorithms() { let ee = include_bytes!("signatures/ecdsa_p256.ee.der"); for algorithm in &[ + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA256, + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA384, #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] ECDSA_P521_SHA512, ECDSA_P384_SHA256, @@ -222,6 +231,10 @@ fn ecdsa_p384_key_and_ecdsa_p384_sha256_detects_bad_signature() { fn ecdsa_p384_key_rejected_by_other_algorithms() { let ee = include_bytes!("signatures/ecdsa_p384.ee.der"); for algorithm in &[ + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA256, + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA384, #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] ECDSA_P521_SHA512, ECDSA_P256_SHA256, @@ -266,6 +279,54 @@ fn ecdsa_p521_key_and_ecdsa_p521_sha512_detects_bad_signature() { ); } +#[test] +#[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] +fn ecdsa_p521_key_and_ecdsa_p521_sha256_good_signature() { + let ee = include_bytes!("signatures/ecdsa_p521.ee.der"); + let message = include_bytes!("signatures/message.bin"); + let signature = + include_bytes!("signatures/ecdsa_p521_key_and_ecdsa_p521_sha256_good_signature.sig.bin"); + assert_eq!(check_sig(ee, ECDSA_P521_SHA256, message, signature), Ok(())); +} + +#[test] +#[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] +fn ecdsa_p521_key_and_ecdsa_p521_sha256_detects_bad_signature() { + let ee = include_bytes!("signatures/ecdsa_p521.ee.der"); + let message = include_bytes!("signatures/message.bin"); + let signature = include_bytes!( + "signatures/ecdsa_p521_key_and_ecdsa_p521_sha256_detects_bad_signature.sig.bin" + ); + assert_eq!( + check_sig(ee, ECDSA_P521_SHA256, message, signature), + Err(webpki::Error::InvalidSignatureForPublicKey) + ); +} + +#[test] +#[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] +fn ecdsa_p521_key_and_ecdsa_p521_sha384_good_signature() { + let ee = include_bytes!("signatures/ecdsa_p521.ee.der"); + let message = include_bytes!("signatures/message.bin"); + let signature = + include_bytes!("signatures/ecdsa_p521_key_and_ecdsa_p521_sha384_good_signature.sig.bin"); + assert_eq!(check_sig(ee, ECDSA_P521_SHA384, message, signature), Ok(())); +} + +#[test] +#[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] +fn ecdsa_p521_key_and_ecdsa_p521_sha384_detects_bad_signature() { + let ee = include_bytes!("signatures/ecdsa_p521.ee.der"); + let message = include_bytes!("signatures/message.bin"); + let signature = include_bytes!( + "signatures/ecdsa_p521_key_and_ecdsa_p521_sha384_detects_bad_signature.sig.bin" + ); + assert_eq!( + check_sig(ee, ECDSA_P521_SHA384, message, signature), + Err(webpki::Error::InvalidSignatureForPublicKey) + ); +} + #[test] #[cfg(feature = "alloc")] fn ecdsa_p521_key_rejected_by_other_algorithms() { @@ -458,6 +519,10 @@ fn rsa_2048_key_and_rsa_pss_2048_8192_sha512_legacy_key_detects_bad_signature() fn rsa_2048_key_rejected_by_other_algorithms() { let ee = include_bytes!("signatures/rsa_2048.ee.der"); for algorithm in &[ + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA256, + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA384, #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] ECDSA_P521_SHA512, ECDSA_P256_SHA256, @@ -668,6 +733,10 @@ fn rsa_3072_key_and_rsa_pkcs1_3072_8192_sha384_detects_bad_signature() { fn rsa_3072_key_rejected_by_other_algorithms() { let ee = include_bytes!("signatures/rsa_3072.ee.der"); for algorithm in &[ + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA256, + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA384, #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] ECDSA_P521_SHA512, ECDSA_P256_SHA256, @@ -878,6 +947,10 @@ fn rsa_4096_key_and_rsa_pkcs1_3072_8192_sha384_detects_bad_signature() { fn rsa_4096_key_rejected_by_other_algorithms() { let ee = include_bytes!("signatures/rsa_4096.ee.der"); for algorithm in &[ + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA256, + #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + ECDSA_P521_SHA384, #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] ECDSA_P521_SHA512, ECDSA_P256_SHA256, diff --git a/tests/signatures/ecdsa_p521.ee.der b/tests/signatures/ecdsa_p521.ee.der index 82faa7936bcf010feccaf36e0f4a658e93917b82..8c7f8640ef73bc7e08775ec238a654e384317479 100644 GIT binary patch delta 440 zcmV;p0Z0DO1keN{FoFV1FoFRzpaTK{0s<6d_@k9WdZwrJz26B|?w*TKiD%=HBZGed z-#y8I{3`$>5BBt_jUgKjeqhyTiqbgdvQlxe&gB|G)n`V{QyEf>%R%4!yuJ!mQXO(hXoSlL4w?YQ@tJt6|_P=C*5 zHRLvIS+WfA+{H@l#tSy42Uwxwv?yw)^^^XV0yz`j@0_}eJFf=^5Kr7)LE#k>T9PVZ iG5(%B2*YXT+C%~fxPT6D30i~`MwKPW+OD_clop$pN;QS**z@-43`dY8^|wI$^@!yj3fzQ0e_&tV#w5!BrjZ35=3K zFQ?yif3a@hIK>~PEv17=Qn*%3N&p4pY9DHxlPUowf3i|oKfHcfMzE7Y`q}D{q_uPG zSo*U|IfcIcwd4xi>L?}?w@cCE0+=#UHgvn|m~OLChtI1!0QbUq=#^Z6%E}*r(`dUN z=cX#K(J7fGj$V`qg;iA+L8&}=I|n!sYk>v+%kdk{<$mdj?M%a`rw7hQl+^aZVB5D2 zzzc@&e+m$iWH=s$wl^vMZQv1zcbkXL1P_PPw0y$Z i6JM)J0_@CLeXfE=DZl^aS$GZzAZg4A{^`|C0-#__fYyxw diff --git a/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha256_detects_bad_signature.sig.bin b/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha256_detects_bad_signature.sig.bin new file mode 100644 index 00000000..a82cd825 --- /dev/null +++ b/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha256_detects_bad_signature.sig.bin @@ -0,0 +1,3 @@ +0BY 8#$c_PE$ TVfٖ0hI?@~9~Xuzݺ ZKP{@zBG]'rUqQ:,t$Ȧ\ۀ +~Аi +[d9#)ۙ; \ No newline at end of file diff --git a/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha256_good_signature.sig.bin b/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha256_good_signature.sig.bin new file mode 100644 index 0000000000000000000000000000000000000000..9093a97d7e575126190df03fb3441d9538117574 GIT binary patch literal 139 zcmV;60CfK_frtV^0e!$E^L`Vm&ZRDcWBcz;ReL&bdizDiF7Z<0G(Wk_aTdM!b2OiU ztEdEC=c+awgWoic$Q2CTR+*V|ejn=f3_Ais0HzweMrWI>hxej0v47fJR6{@v;EOr0 tq|FO8oh_>c>F)l-p7#^CQo|A5?#!QDqPpp*W0o{gP6blTAKDwSkU3LtL^}Wg literal 0 HcmV?d00001 diff --git a/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha384_detects_bad_signature.sig.bin b/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha384_detects_bad_signature.sig.bin new file mode 100644 index 0000000000000000000000000000000000000000..a4b97b4e5377e18489119e1b4af9a67e9a99fe24 GIT binary patch literal 139 zcmV;60CfK_frtV^0Ib!&TVELAq$0x?7d^l-#(wndEMr4r_-(?%!xw{HDUJ;h4A{j4 zz+9p40)W}CGg~s8YuXr$uQF~3vgLQEzLo+)0YwC1bJ;kfl?yM;KSMrq_CU}TGpFcK tMA8N9^ogcg_>T;GRkhiixv3n(3ZQN9w9u0^MI@+|f2j4#-5k1ULD^ngLaG1& literal 0 HcmV?d00001 diff --git a/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha384_good_signature.sig.bin b/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha384_good_signature.sig.bin new file mode 100644 index 00000000..1ba5074d --- /dev/null +++ b/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha384_good_signature.sig.bin @@ -0,0 +1,2 @@ +0Amұ'nM6ry}H 0tOo(v@H^l$ ~Ks-BC +ZK#50'"kiwĢFzYuf#5VkGoVM4g \ No newline at end of file diff --git a/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha512_detects_bad_signature.sig.bin b/tests/signatures/ecdsa_p521_key_and_ecdsa_p521_sha512_detects_bad_signature.sig.bin index 5fcb76c305d73f195ebc3161011999ff98bce829..067bc5599e8a32b30109757887049cbe2becad0b 100644 GIT binary patch literal 139 zcmV;60CfK_frtV^0Rep3E;INcuVnv1%Z~x1UhH!Uy31JXJ)^)wY?2puS)_#0Ec{GUbvxk_63O2OrbO`Vk>M!npS5q tUINb;SR_f14LVdHq#WO1SI&g=%+9&O!PDAIoy$l?S!{Dxl(>;K!v?(uK)L_` literal 138 zcmV;50CoQ`frkP@0lW03Dlh?C5tv?*>U%rg*xxKKjl+7Vw9`4I+XG