From 2818524bf4ef89b00e1dcc481dc04d91e1a8490a Mon Sep 17 00:00:00 2001 From: 42Pupusas Date: Fri, 16 Oct 2026 15:17:25 -0600 Subject: [PATCH 1/2] Set AES-GCM record confidentiality limits Every AES-GCM suite declared confidentiality_limit u64::MAX, which disables rustls' bound on how many records may be sealed with one key before the connection must be replaced. This copies the record-level limits used by rustls' own ring and aws-lc-rs providers: 1 << 24 for every AES-GCM suite, TLS 1.2 and TLS 1.3 alike. (The 1 << 23 values in those providers belong to their QUIC KeyBuilder blocks, a separate field for packet protection, not the record limit.) The ChaCha20Poly1305 suites keep u64::MAX, matching both providers, which cite draft-irtf-cfrg-aead-limits section 5.2.1 there. A regression test pins the limits for the four suites exported from the crate root. --- src/lib.rs | 14 ++++++++------ src/limit_tests.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 src/limit_tests.rs diff --git a/src/lib.rs b/src/lib.rs index 6332bca..2110644 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,7 +103,7 @@ pub const TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite = common: CipherSuiteCommon { suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, hash_provider: hash::SHA256, - confidentiality_limit: u64::MAX, + confidentiality_limit: 1 << 24, }, kx: rustls::crypto::KeyExchangeAlgorithm::ECDHE, sign: &TLS12_ECDSA_SCHEMES, @@ -117,7 +117,7 @@ pub const TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite = common: CipherSuiteCommon { suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, hash_provider: hash::SHA384, - confidentiality_limit: u64::MAX, + confidentiality_limit: 1 << 24, }, kx: rustls::crypto::KeyExchangeAlgorithm::ECDHE, sign: &TLS12_ECDSA_SCHEMES, @@ -152,7 +152,7 @@ pub const TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite = common: CipherSuiteCommon { suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, hash_provider: hash::SHA256, - confidentiality_limit: u64::MAX, + confidentiality_limit: 1 << 24, }, kx: rustls::crypto::KeyExchangeAlgorithm::ECDHE, sign: &TLS12_RSA_SCHEMES, @@ -166,7 +166,7 @@ pub const TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite = common: CipherSuiteCommon { suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, hash_provider: hash::SHA384, - confidentiality_limit: u64::MAX, + confidentiality_limit: 1 << 24, }, kx: rustls::crypto::KeyExchangeAlgorithm::ECDHE, sign: &TLS12_RSA_SCHEMES, @@ -210,7 +210,7 @@ pub const TLS13_AES_128_GCM_SHA256: SupportedCipherSuite = common: CipherSuiteCommon { suite: CipherSuite::TLS13_AES_128_GCM_SHA256, hash_provider: hash::SHA256, - confidentiality_limit: u64::MAX, + confidentiality_limit: 1 << 24, }, hkdf_provider: &rustls::crypto::tls13::HkdfUsingHmac(hmac::SHA256), aead_alg: &aead::gcm::Tls13Aes128Gcm, @@ -222,7 +222,7 @@ pub const TLS13_AES_256_GCM_SHA384: SupportedCipherSuite = common: CipherSuiteCommon { suite: CipherSuite::TLS13_AES_256_GCM_SHA384, hash_provider: hash::SHA384, - confidentiality_limit: u64::MAX, + confidentiality_limit: 1 << 24, }, hkdf_provider: &rustls::crypto::tls13::HkdfUsingHmac(hmac::SHA384), aead_alg: &aead::gcm::Tls13Aes256Gcm, @@ -263,6 +263,8 @@ static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = misc::const_concat_slices!( mod aead; mod hash; mod hmac; +#[cfg(test)] +mod limit_tests; mod kx; mod misc; pub mod quic; diff --git a/src/limit_tests.rs b/src/limit_tests.rs new file mode 100644 index 0000000..2a89dd6 --- /dev/null +++ b/src/limit_tests.rs @@ -0,0 +1,40 @@ +use crate::{ + TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, +}; +use rustls::{CipherSuite, SupportedCipherSuite}; + +#[test] +fn aes_gcm_confidentiality_limits_match_the_reference_providers() { + let limits = [ + ( + &TLS13_AES_128_GCM_SHA256, + CipherSuite::TLS13_AES_128_GCM_SHA256, + 1 << 24, + ), + ( + &TLS13_AES_256_GCM_SHA384, + CipherSuite::TLS13_AES_256_GCM_SHA384, + 1 << 24, + ), + #[cfg(feature = "tls12")] + ( + &TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + 1 << 24, + ), + #[cfg(feature = "tls12")] + ( + &TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + 1 << 24, + ), + ]; + for (suite, suite_id, expected) in limits { + let actual = match suite { + SupportedCipherSuite::Tls13(inner) => inner.common.confidentiality_limit, + SupportedCipherSuite::Tls12(inner) => inner.common.confidentiality_limit, + }; + assert_eq!(actual, expected, "{suite_id:?}"); + } +} From 456953fdbe3b3d025065dbfb72e88270a12780a6 Mon Sep 17 00:00:00 2001 From: 42Pupusas Date: Fri, 16 Oct 2026 15:52:55 -0600 Subject: [PATCH 2/2] Fix module declaration order in lib.rs The new limit_tests module was declared before kx; rustfmt orders module declarations alphabetically. cargo fmt --all -- --check is clean now. --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 2110644..c6dacf2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -263,9 +263,9 @@ static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = misc::const_concat_slices!( mod aead; mod hash; mod hmac; +mod kx; #[cfg(test)] mod limit_tests; -mod kx; mod misc; pub mod quic; pub mod sign;