suites: split integrity and confidentiality limit handling

Previously the `CipherSuiteCommon` type had a `confidentiality_limit`
and a `integrity_limit`. Recent refactoring for better downstream
QUIC ergonomics has pulled these limits into the `quic::PacketKey`
trait. To reduce duplication this commit adjusts our handling of these
two limits.

For the `integrity_limit`, it was already documented in
`CipherSuiteCommon` as being specific to QUIC and irrelevant for TLS
over TCP. For this reason we delete the field from `CipherSuiteCommon`,
leaving it only in `quic::PacketKey` where it is actually useful.

For the `confidentiality_limit` it was described imprecisely and erred
on the side of caution, proposing a limit calculated based on QUIC
overhead even for the TCP usecase. Now that we've split this field the
`CipherSuiteCommon` version's documentation is updated to use a tighter
bound for the TCP use-case, and the associated `PacketKey` field can be
documented to use the QUIC bound.
This commit is contained in:
Daniel McCarney 2024-02-14 16:12:03 -05:00
parent 542b12ca89
commit 5138cd81e1
8 changed files with 21 additions and 49 deletions

View File

@ -71,7 +71,6 @@ pub static TLS13_CHACHA20_POLY1305_SHA256: rustls::SupportedCipherSuite =
suite: rustls::CipherSuite::TLS13_CHACHA20_POLY1305_SHA256, suite: rustls::CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
hash_provider: &hash::Sha256, hash_provider: &hash::Sha256,
confidentiality_limit: u64::MAX, confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
}, },
hkdf_provider: &rustls::crypto::tls13::HkdfUsingHmac(&hmac::Sha256Hmac), hkdf_provider: &rustls::crypto::tls13::HkdfUsingHmac(&hmac::Sha256Hmac),
aead_alg: &aead::Chacha20Poly1305, aead_alg: &aead::Chacha20Poly1305,
@ -84,7 +83,6 @@ pub static TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: rustls::SupportedCipherS
suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
hash_provider: &hash::Sha256, hash_provider: &hash::Sha256,
confidentiality_limit: u64::MAX, confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
}, },
kx: rustls::crypto::KeyExchangeAlgorithm::ECDHE, kx: rustls::crypto::KeyExchangeAlgorithm::ECDHE,
sign: &[ sign: &[

View File

@ -25,7 +25,6 @@ pub static TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX, confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_ECDSA_SCHEMES, sign: TLS12_ECDSA_SCHEMES,
@ -40,7 +39,6 @@ pub static TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, suite: CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX, confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_RSA_SCHEMES, sign: TLS12_RSA_SCHEMES,
@ -55,7 +53,6 @@ pub static TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_RSA_SCHEMES, sign: TLS12_RSA_SCHEMES,
@ -70,7 +67,6 @@ pub static TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
hash_provider: &super::hash::SHA384, hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_RSA_SCHEMES, sign: TLS12_RSA_SCHEMES,
@ -85,7 +81,6 @@ pub static TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_ECDSA_SCHEMES, sign: TLS12_ECDSA_SCHEMES,
@ -100,7 +95,6 @@ pub static TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
hash_provider: &super::hash::SHA384, hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_ECDSA_SCHEMES, sign: TLS12_ECDSA_SCHEMES,

View File

@ -26,7 +26,6 @@ pub(crate) static TLS13_CHACHA20_POLY1305_SHA256_INTERNAL: &Tls13CipherSuite = &
suite: CipherSuite::TLS13_CHACHA20_POLY1305_SHA256, suite: CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX, confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
}, },
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256), hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256),
aead_alg: &Chacha20Poly1305Aead(AeadAlgorithm(&aead::CHACHA20_POLY1305)), aead_alg: &Chacha20Poly1305Aead(AeadAlgorithm(&aead::CHACHA20_POLY1305)),
@ -45,7 +44,6 @@ pub static TLS13_AES_256_GCM_SHA384: SupportedCipherSuite =
suite: CipherSuite::TLS13_AES_256_GCM_SHA384, suite: CipherSuite::TLS13_AES_256_GCM_SHA384,
hash_provider: &super::hash::SHA384, hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA384, hmac::HMAC_SHA384), hkdf_provider: &RingHkdf(hkdf::HKDF_SHA384, hmac::HMAC_SHA384),
aead_alg: &Aes256GcmAead(AeadAlgorithm(&aead::AES_256_GCM)), aead_alg: &Aes256GcmAead(AeadAlgorithm(&aead::AES_256_GCM)),
@ -66,7 +64,6 @@ pub(crate) static TLS13_AES_128_GCM_SHA256_INTERNAL: &Tls13CipherSuite = &Tls13C
suite: CipherSuite::TLS13_AES_128_GCM_SHA256, suite: CipherSuite::TLS13_AES_128_GCM_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256), hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256),
aead_alg: &Aes128GcmAead(AeadAlgorithm(&aead::AES_128_GCM)), aead_alg: &Aes128GcmAead(AeadAlgorithm(&aead::AES_128_GCM)),

View File

@ -100,13 +100,9 @@ pub(crate) struct PacketKey {
key: aead::LessSafeKey, key: aead::LessSafeKey,
/// Computes unique nonces for each packet /// Computes unique nonces for each packet
iv: Iv, iv: Iv,
/// Confidentiality limit (see [`CipherSuiteCommon::confidentiality_limit`][csc-limit]) /// Confidentiality limit (see [`quic::PacketKey::confidentiality_limit`])
///
/// [csc-limit]: crate::crypto::CipherSuiteCommon::confidentiality_limit
confidentiality_limit: u64, confidentiality_limit: u64,
/// Integrity limit (see [`CipherSuiteCommon::integrity_limit`][csc-limit]) /// Integrity limit (see [`quic::PacketKey::integrity_limit`])
///
/// [csc-limit]: crate::crypto::CipherSuiteCommon::integrity_limit
integrity_limit: u64, integrity_limit: u64,
} }
@ -175,16 +171,12 @@ impl quic::PacketKey for PacketKey {
self.key.algorithm().tag_len() self.key.algorithm().tag_len()
} }
/// Confidentiality limit (see [`CipherSuiteCommon::confidentiality_limit`][csc-limit]) /// Confidentiality limit (see [`quic::PacketKey::confidentiality_limit`])
///
/// [csc-limit]: crate::crypto::CipherSuiteCommon::confidentiality_limit
fn confidentiality_limit(&self) -> u64 { fn confidentiality_limit(&self) -> u64 {
self.confidentiality_limit self.confidentiality_limit
} }
/// Integrity limit (see [`CipherSuiteCommon::integrity_limit`][csc-limit]) /// Integrity limit (see [`quic::PacketKey::integrity_limit`])
///
/// [csc-limit]: crate::crypto::CipherSuiteCommon::integrity_limit
fn integrity_limit(&self) -> u64 { fn integrity_limit(&self) -> u64 {
self.integrity_limit self.integrity_limit
} }

View File

@ -24,7 +24,6 @@ pub static TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX, confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_ECDSA_SCHEMES, sign: TLS12_ECDSA_SCHEMES,
@ -39,7 +38,6 @@ pub static TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, suite: CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX, confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_RSA_SCHEMES, sign: TLS12_RSA_SCHEMES,
@ -54,7 +52,6 @@ pub static TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_RSA_SCHEMES, sign: TLS12_RSA_SCHEMES,
@ -69,7 +66,6 @@ pub static TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
hash_provider: &super::hash::SHA384, hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_RSA_SCHEMES, sign: TLS12_RSA_SCHEMES,
@ -84,7 +80,6 @@ pub static TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_ECDSA_SCHEMES, sign: TLS12_ECDSA_SCHEMES,
@ -99,7 +94,6 @@ pub static TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, suite: CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
hash_provider: &super::hash::SHA384, hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
kx: KeyExchangeAlgorithm::ECDHE, kx: KeyExchangeAlgorithm::ECDHE,
sign: TLS12_ECDSA_SCHEMES, sign: TLS12_ECDSA_SCHEMES,

View File

@ -26,7 +26,6 @@ pub(crate) static TLS13_CHACHA20_POLY1305_SHA256_INTERNAL: &Tls13CipherSuite = &
suite: CipherSuite::TLS13_CHACHA20_POLY1305_SHA256, suite: CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX, confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
}, },
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256), hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256),
aead_alg: &Chacha20Poly1305Aead(AeadAlgorithm(&aead::CHACHA20_POLY1305)), aead_alg: &Chacha20Poly1305Aead(AeadAlgorithm(&aead::CHACHA20_POLY1305)),
@ -45,7 +44,6 @@ pub static TLS13_AES_256_GCM_SHA384: SupportedCipherSuite =
suite: CipherSuite::TLS13_AES_256_GCM_SHA384, suite: CipherSuite::TLS13_AES_256_GCM_SHA384,
hash_provider: &super::hash::SHA384, hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA384, hmac::HMAC_SHA384), hkdf_provider: &RingHkdf(hkdf::HKDF_SHA384, hmac::HMAC_SHA384),
aead_alg: &Aes256GcmAead(AeadAlgorithm(&aead::AES_256_GCM)), aead_alg: &Aes256GcmAead(AeadAlgorithm(&aead::AES_256_GCM)),
@ -66,7 +64,6 @@ pub(crate) static TLS13_AES_128_GCM_SHA256_INTERNAL: &Tls13CipherSuite = &Tls13C
suite: CipherSuite::TLS13_AES_128_GCM_SHA256, suite: CipherSuite::TLS13_AES_128_GCM_SHA256,
hash_provider: &super::hash::SHA256, hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23, confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
}, },
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256), hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256),
aead_alg: &Aes128GcmAead(AeadAlgorithm(&aead::AES_128_GCM)), aead_alg: &Aes128GcmAead(AeadAlgorithm(&aead::AES_128_GCM)),

View File

@ -706,18 +706,26 @@ pub trait PacketKey: Send + Sync {
/// Tag length for the underlying AEAD algorithm /// Tag length for the underlying AEAD algorithm
fn tag_len(&self) -> usize; fn tag_len(&self) -> usize;
/// Number of messages that can be safely encrypted with a single key of this type. /// Number of QUIC messages that can be safely encrypted with a single key of this type.
/// ///
/// See [`CipherSuiteCommon::confidentiality_limit`][csc-limit]. /// Once a `MessageEncrypter` produced for this suite has encrypted more than
/// `confidentiality_limit` messages, an attacker gains an advantage in distinguishing it
/// from an ideal pseudorandom permutation (PRP).
///
/// This is to be set on the assumption that messages are maximally sized --
/// 2 ** 16. For non-QUIC TCP connections see [`CipherSuiteCommon::confidentiality_limit`][csc-limit].
/// ///
/// [csc-limit]: crate::crypto::CipherSuiteCommon::confidentiality_limit /// [csc-limit]: crate::crypto::CipherSuiteCommon::confidentiality_limit
fn confidentiality_limit(&self) -> u64; fn confidentiality_limit(&self) -> u64;
/// Number of messages that can be safely authenticated with a single key of this type. /// Number of QUIC messages that can be safely decrypted with a single key of this type
/// ///
/// See [`CipherSuiteCommon::integrity_limit`][csc-limit]. /// Once a `MessageDecrypter` produced for this suite has failed to decrypt `integrity_limit`
/// messages, an attacker gains an advantage in forging messages.
/// ///
/// [csc-limit]: crate::crypto::CipherSuiteCommon::integrity_limit /// This is not relevant for TLS over TCP (which is implemented in this crate)
/// because a single failed decryption is fatal to the connection. However,
/// this quantity is used by QUIC.
fn integrity_limit(&self) -> u64; fn integrity_limit(&self) -> u64;
} }

View File

@ -20,25 +20,17 @@ pub struct CipherSuiteCommon {
/// Which hash function the suite uses. /// Which hash function the suite uses.
pub hash_provider: &'static dyn crypto::hash::Hash, pub hash_provider: &'static dyn crypto::hash::Hash,
/// Number of messages that can be safely encrypted with a single key of this type /// Number of TCP-TLS messages that can be safely encrypted with a single key of this type
/// ///
/// Once a `MessageEncrypter` produced for this suite has encrypted more than /// Once a `MessageEncrypter` produced for this suite has encrypted more than
/// `confidentiality_limit` messages, an attacker gains an advantage in distinguishing it /// `confidentiality_limit` messages, an attacker gains an advantage in distinguishing it
/// from an ideal pseudorandom permutation (PRP). /// from an ideal pseudorandom permutation (PRP).
/// ///
/// This is to be set on the assumption that messages are maximally sized -- /// This is to be set on the assumption that messages are maximally sized --
/// at least 2 ** 14 bytes for TCP-TLS and 2 ** 16 for QUIC. /// at least 2 ** 14 bytes. It **does not** consider confidentiality limits for
/// QUIC connections - see the [`quic::KeyBuilder.confidentiality_limit`] field for
/// this context.
pub confidentiality_limit: u64, pub confidentiality_limit: u64,
/// Number of messages that can be safely decrypted with a single key of this type
///
/// Once a `MessageDecrypter` produced for this suite has failed to decrypt `integrity_limit`
/// messages, an attacker gains an advantage in forging messages.
///
/// This is not relevant for TLS over TCP (which is implemented in this crate)
/// because a single failed decryption is fatal to the connection. However,
/// this quantity is used by QUIC.
pub integrity_limit: u64,
} }
impl CipherSuiteCommon { impl CipherSuiteCommon {