From c8dbf855a121f21f066b4241790cac0d32772fc7 Mon Sep 17 00:00:00 2001 From: Alex Weibel Date: Mon, 6 Jan 2025 15:31:12 -0800 Subject: [PATCH] Migrate PQ Rust code to TLS 1.3 --- .../rust/extended/s2n-tls/src/connection.rs | 28 +++++++++++++++++++ .../extended/s2n-tls/src/testing/s2n_tls.rs | 4 +-- bindings/rust/standard/integration/src/lib.rs | 4 +-- .../integration/src/network/tls_client.rs | 27 ++---------------- 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/bindings/rust/extended/s2n-tls/src/connection.rs b/bindings/rust/extended/s2n-tls/src/connection.rs index 7db69da50bf..f6106298b7f 100644 --- a/bindings/rust/extended/s2n-tls/src/connection.rs +++ b/bindings/rust/extended/s2n-tls/src/connection.rs @@ -1000,6 +1000,34 @@ impl Connection { } } + pub fn kem_group_name(&self) -> Option<&str> { + let name_bytes = { + let name = unsafe { s2n_connection_get_kem_group_name(self.connection.as_ptr()) }; + if name.is_null() { + return None; + } + name + }; + + let name_str = unsafe { + // SAFETY: The data is null terminated because it is declared as a C + // string literal. + // SAFETY: kem_name has a static lifetime because it lives on a const + // struct s2n_kem with file scope. + const_str!(name_bytes) + }; + + match name_str { + Ok("NONE") => None, + Ok(name) => Some(name), + Err(_) => { + // Unreachable: This would indicate a non-utf-8 string literal in + // the s2n-tls C codebase. + None + } + } + } + pub fn selected_curve(&self) -> Result<&str, Error> { let curve = unsafe { s2n_connection_get_curve(self.connection.as_ptr()).into_result()? }; unsafe { diff --git a/bindings/rust/extended/s2n-tls/src/testing/s2n_tls.rs b/bindings/rust/extended/s2n-tls/src/testing/s2n_tls.rs index 1d5d920c384..1d4ee6fcfe4 100644 --- a/bindings/rust/extended/s2n-tls/src/testing/s2n_tls.rs +++ b/bindings/rust/extended/s2n-tls/src/testing/s2n_tls.rs @@ -44,12 +44,12 @@ mod tests { // PQ is supported { - let policy = Policy::from_version("KMS-PQ-TLS-1-0-2020-07")?; + let policy = Policy::from_version("default_pq")?; let config = build_config(&policy)?; let mut pair = TestPair::from_config(&config); pair.handshake().unwrap(); - assert_eq!(pair.client.kem_name(), Some("kyber512r3")); + assert_eq!(pair.client.kem_group_name(), Some("X25519MLKEM768")); } Ok(()) diff --git a/bindings/rust/standard/integration/src/lib.rs b/bindings/rust/standard/integration/src/lib.rs index 25252295875..93b9f4c4adf 100644 --- a/bindings/rust/standard/integration/src/lib.rs +++ b/bindings/rust/standard/integration/src/lib.rs @@ -16,11 +16,11 @@ mod tests { #[cfg(feature = "pq")] #[test] fn pq_sanity_check() -> Result<(), Box> { - let config = testing::build_config(&Policy::from_version("KMS-PQ-TLS-1-0-2020-07")?)?; + let config = testing::build_config(&Policy::from_version("default_pq")?)?; let mut pair = TestPair::from_config(&config); pair.handshake()?; - if pair.client.kem_name().is_none() { + if pair.client.kem_group_name().is_none() { panic!( "PQ tests are enabled, but PQ functionality is unavailable. \ Are you sure that the libcrypto supports PQ?" diff --git a/bindings/rust/standard/integration/src/network/tls_client.rs b/bindings/rust/standard/integration/src/network/tls_client.rs index caef998abf7..9aba9887282 100644 --- a/bindings/rust/standard/integration/src/network/tls_client.rs +++ b/bindings/rust/standard/integration/src/network/tls_client.rs @@ -46,38 +46,17 @@ mod kms_pq { // supports ML-KEM. #[test_log::test(tokio::test)] async fn pq_handshake() -> Result<(), Box> { - let policy = Policy::from_version("KMS-PQ-TLS-1-0-2020-07")?; + let policy = Policy::from_version("PQ-TLS-1-2-2023-10-09")?; let tls = handshake_with_domain(DOMAIN, &policy).await?; assert_eq!( tls.as_ref().cipher_suite()?, - "ECDHE-KYBER-RSA-AES256-GCM-SHA384" + "TLS_AES_256_GCM_SHA384" ); - assert_eq!(tls.as_ref().kem_name(), Some("kyber512r3")); + assert_eq!(tls.as_ref().kem_group_name(), Some("x25519_kyber-512-r3")); Ok(()) } - - // We want to confirm that non-supported kyber drafts successfully fall - // back to a full handshake. - #[test_log::test(tokio::test)] - async fn early_draft_falls_back_to_classical() -> Result<(), Box> { - const EARLY_DRAFT_PQ_POLICIES: &[&str] = &[ - "KMS-PQ-TLS-1-0-2019-06", - "PQ-SIKE-TEST-TLS-1-0-2019-11", - "KMS-PQ-TLS-1-0-2020-02", - "PQ-SIKE-TEST-TLS-1-0-2020-02", - ]; - - for security_policy in EARLY_DRAFT_PQ_POLICIES { - let policy = Policy::from_version(security_policy)?; - let tls = handshake_with_domain(DOMAIN, &policy).await?; - - assert_eq!(tls.as_ref().cipher_suite()?, "ECDHE-RSA-AES256-GCM-SHA384"); - assert_eq!(tls.as_ref().kem_name(), None); - } - Ok(()) - } } #[test_log::test(tokio::test)]