From 768a1a66337d76aa73db0edc3564a4600015b38a Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Mon, 12 Aug 2024 18:13:00 +0200 Subject: [PATCH] p256 --- Cargo.lock | 152 ++++++++++++++++++++++++++++++++++++++ ssh-transport/Cargo.toml | 1 + ssh-transport/src/keys.rs | 23 ++++++ ssh-transport/src/lib.rs | 4 +- 4 files changed, 179 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 26ceb9f..491b02f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,6 +47,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64ct" version = "1.6.0" @@ -128,6 +134,18 @@ dependencies = [ "libc", ] +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -172,6 +190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", + "pem-rfc7468", "zeroize", ] @@ -182,7 +201,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", ] [[package]] @@ -209,6 +244,27 @@ dependencies = [ "zeroize", ] +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "eyre" version = "0.6.12" @@ -231,6 +287,16 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "fiat-crypto" version = "0.2.9" @@ -245,6 +311,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -264,6 +331,17 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "hermit-abi" version = "0.3.9" @@ -276,6 +354,24 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "indenter" version = "0.3.3" @@ -398,6 +494,18 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "parking_lot" version = "0.12.3" @@ -421,6 +529,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -457,6 +574,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -558,6 +684,16 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -585,6 +721,20 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "semver" version = "1.0.23" @@ -658,6 +808,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ + "digest", "rand_core", ] @@ -712,6 +863,7 @@ dependencies = [ "ed25519-dalek", "eyre", "hex-literal", + "p256", "poly1305", "rand", "rand_core", diff --git a/ssh-transport/Cargo.toml b/ssh-transport/Cargo.toml index 715b9c7..26bbbd7 100644 --- a/ssh-transport/Cargo.toml +++ b/ssh-transport/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" chacha20 = "0.9.1" ed25519-dalek = { version = "2.1.1" } eyre = "0.6.12" +p256 = { version = "0.13.2", features = ["ecdh"] } poly1305 = "0.8.0" rand = "0.8.5" rand_core = "0.6.4" diff --git a/ssh-transport/src/keys.rs b/ssh-transport/src/keys.rs index c4ffb58..122a567 100644 --- a/ssh-transport/src/keys.rs +++ b/ssh-transport/src/keys.rs @@ -45,6 +45,29 @@ pub const KEX_CURVE_25519_SHA256: KexAlgorithm = KexAlgorithm { }) }, }; +/// +pub const KEX_ECDH_SHA2_NISTP256: KexAlgorithm = KexAlgorithm { + name: "ecdh-sha2-nistp256", + exchange: |client_public_key, rng| { + let secret = p256::ecdh::EphemeralSecret::random(&mut crate::SshRngRandAdapter(rng)); + let server_public_key = p256::EncodedPoint::from(secret.public_key()); // Q_S + + let client_public_key = + p256::PublicKey::from_sec1_bytes(client_public_key).map_err(|_| { + crate::client_error!( + "invalid p256 public key length: {}", + client_public_key.len() + ) + })?; // Q_C + + let shared_secret = secret.diffie_hellman(&client_public_key); // K + + Ok(KexAlgorithmOutput { + server_public_key: server_public_key.as_bytes().to_vec(), + shared_secret: shared_secret.raw_secret_bytes().to_vec(), + }) + }, +}; pub struct AlgorithmNegotiation { pub supported: Vec<(&'static str, T)>, diff --git a/ssh-transport/src/lib.rs b/ssh-transport/src/lib.rs index bba5bc9..139326b 100644 --- a/ssh-transport/src/lib.rs +++ b/ssh-transport/src/lib.rs @@ -175,11 +175,13 @@ impl ServerConnection { } }; - // TODO: support ecdh-sha2-nistp256 let kex_algorithms = AlgorithmNegotiation { supported: vec![( keys::KEX_CURVE_25519_SHA256.name, keys::KEX_CURVE_25519_SHA256, + ), ( + keys::KEX_ECDH_SHA2_NISTP256.name, + keys::KEX_ECDH_SHA2_NISTP256, )], }; let kex_algorithm = kex_algorithms.find(kex.kex_algorithms.0)?;