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,
hash_provider: &hash::Sha256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},
hkdf_provider: &rustls::crypto::tls13::HkdfUsingHmac(&hmac::Sha256Hmac),
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,
hash_provider: &hash::Sha256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},
kx: rustls::crypto::KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256),
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,
hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA384, hmac::HMAC_SHA384),
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256),
aead_alg: &Aes128GcmAead(AeadAlgorithm(&aead::AES_128_GCM)),

View File

@ -100,13 +100,9 @@ pub(crate) struct PacketKey {
key: aead::LessSafeKey,
/// Computes unique nonces for each packet
iv: Iv,
/// Confidentiality limit (see [`CipherSuiteCommon::confidentiality_limit`][csc-limit])
///
/// [csc-limit]: crate::crypto::CipherSuiteCommon::confidentiality_limit
/// Confidentiality limit (see [`quic::PacketKey::confidentiality_limit`])
confidentiality_limit: u64,
/// Integrity limit (see [`CipherSuiteCommon::integrity_limit`][csc-limit])
///
/// [csc-limit]: crate::crypto::CipherSuiteCommon::integrity_limit
/// Integrity limit (see [`quic::PacketKey::integrity_limit`])
integrity_limit: u64,
}
@ -175,16 +171,12 @@ impl quic::PacketKey for PacketKey {
self.key.algorithm().tag_len()
}
/// Confidentiality limit (see [`CipherSuiteCommon::confidentiality_limit`][csc-limit])
///
/// [csc-limit]: crate::crypto::CipherSuiteCommon::confidentiality_limit
/// Confidentiality limit (see [`quic::PacketKey::confidentiality_limit`])
fn confidentiality_limit(&self) -> u64 {
self.confidentiality_limit
}
/// Integrity limit (see [`CipherSuiteCommon::integrity_limit`][csc-limit])
///
/// [csc-limit]: crate::crypto::CipherSuiteCommon::integrity_limit
/// Integrity limit (see [`quic::PacketKey::integrity_limit`])
fn integrity_limit(&self) -> u64 {
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
kx: KeyExchangeAlgorithm::ECDHE,
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: u64::MAX,
integrity_limit: 1 << 36,
},
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256),
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,
hash_provider: &super::hash::SHA384,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA384, hmac::HMAC_SHA384),
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,
hash_provider: &super::hash::SHA256,
confidentiality_limit: 1 << 23,
integrity_limit: 1 << 52,
},
hkdf_provider: &RingHkdf(hkdf::HKDF_SHA256, hmac::HMAC_SHA256),
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
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
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;
}

View File

@ -20,25 +20,17 @@ pub struct CipherSuiteCommon {
/// Which hash function the suite uses.
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
/// `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 --
/// 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,
/// 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 {