use super::*;
impl Connection {
pub fn noxtls_seal_server_record(
&mut self,
plaintext: &[u8],
aad: &[u8],
) -> Result<ProtectedRecord> {
let handshake_seal_allowed = self.version.uses_tls13_handshake_semantics()
&& self.tls_role == TlsRole::Server
&& self.state == HandshakeState::KeysDerived;
if self.state != HandshakeState::Finished && !handshake_seal_allowed {
return Err(Error::StateError(
"cannot seal server record before handshake completion or tls13 server handshake flight",
));
}
if plaintext.len() > self.max_record_plaintext_len {
return Err(Error::InvalidLength(
"record plaintext exceeds configured limit",
));
}
if self.server_sequence == u64::MAX {
return Err(Error::StateError("server record sequence exhausted"));
}
let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
"cipher suite must be selected before sealing server records",
))?;
let key = self
.server_write_key
.ok_or(Error::StateError("server write key is not installed"))?;
let iv = self
.server_write_iv
.ok_or(Error::StateError("server write iv is not installed"))?;
let nonce = noxtls_build_record_nonce(&iv, self.server_sequence);
let (ciphertext, tag) =
Self::noxtls_aead_encrypt_for_suite(suite, &key, &nonce, aad, plaintext)?;
let record = ProtectedRecord {
sequence: self.server_sequence,
ciphertext,
tag,
};
self.server_sequence = self.server_sequence.wrapping_add(1);
Ok(record)
}
pub fn noxtls_open_client_record(
&mut self,
record: &ProtectedRecord,
aad: &[u8],
) -> Result<Vec<u8>> {
let tls13_handshake_open_allowed = self.version.uses_tls13_handshake_semantics()
&& self.tls_role == TlsRole::Server
&& self.state == HandshakeState::KeysDerived;
if self.state != HandshakeState::Finished && !tls13_handshake_open_allowed {
return Err(Error::StateError(
"cannot open client record before handshake completion or tls13 server handshake flight",
));
}
if self.client_sequence == u64::MAX {
return Err(Error::StateError("client record sequence exhausted"));
}
if record.sequence != self.client_sequence {
return Err(Error::StateError(
"unexpected client record sequence number",
));
}
let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
"cipher suite must be selected before opening client records",
))?;
let key = self
.client_write_key
.ok_or(Error::StateError("client write key is not installed"))?;
let iv = self
.client_write_iv
.ok_or(Error::StateError("client write iv is not installed"))?;
let nonce = noxtls_build_record_nonce(&iv, record.sequence);
let plaintext = Self::noxtls_aead_decrypt_for_suite(
suite,
&key,
&nonce,
aad,
&record.ciphertext,
&record.tag,
)?;
let plaintext_limit = if self.version.uses_tls13_handshake_semantics() {
self.max_record_plaintext_len.saturating_add(1)
} else {
self.max_record_plaintext_len
};
if plaintext.len() > plaintext_limit {
return Err(Error::InvalidLength(
"record plaintext exceeds configured limit",
));
}
self.client_sequence = self.client_sequence.wrapping_add(1);
Ok(plaintext)
}
pub fn noxtls_open_client_tls12_record_packet(
&mut self,
packet: &[u8],
) -> Result<(RecordContentType, Vec<u8>)> {
self.noxtls_ensure_tls12_wire_mode()?;
let sequence = self.client_sequence;
let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
"cipher suite must be selected before opening client tls12 record packet",
))?;
if suite.noxtls_tls12_cbc_key_len().is_some() {
return self.noxtls_open_client_tls12_cbc_record_packet(packet, sequence, suite);
}
if suite.noxtls_tls12_chacha20_poly1305_key_len().is_some() {
return self
.noxtls_open_client_tls12_chacha20_poly1305_record_packet(packet, sequence, suite);
}
let (record, content_type, explicit_nonce) =
self.noxtls_decode_tls12_record_packet(packet, sequence)?;
let key = self
.client_write_key
.ok_or(Error::StateError("client write key is not installed"))?;
let iv = self
.client_write_iv
.ok_or(Error::StateError("client write iv is not installed"))?;
let nonce = Self::noxtls_build_tls12_aead_nonce(&iv, &explicit_nonce);
let aad =
self.noxtls_build_tls12_record_aad(sequence, content_type, record.ciphertext.len())?;
let plaintext = Self::noxtls_aead_decrypt_for_suite(
suite,
&key,
&nonce,
&aad,
&record.ciphertext,
&record.tag,
)?;
if plaintext.len() > self.max_record_plaintext_len {
return Err(Error::InvalidLength(
"record plaintext exceeds configured limit",
));
}
self.client_sequence = self.client_sequence.wrapping_add(1);
Ok((content_type, plaintext))
}
pub fn noxtls_seal_server_tls12_record_packet(
&mut self,
plaintext: &[u8],
content_type: RecordContentType,
) -> Result<Vec<u8>> {
self.noxtls_ensure_tls12_wire_mode()?;
if plaintext.len() > self.max_record_plaintext_len {
return Err(Error::InvalidLength(
"record plaintext exceeds configured limit",
));
}
if self.server_sequence == u64::MAX {
return Err(Error::StateError("server record sequence exhausted"));
}
let sequence = self.server_sequence;
let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
"cipher suite must be selected before sealing server tls12 record packet",
))?;
if suite.noxtls_tls12_cbc_key_len().is_some() {
return self.noxtls_seal_server_tls12_cbc_record_packet(
plaintext,
content_type,
sequence,
suite,
);
}
if suite.noxtls_tls12_chacha20_poly1305_key_len().is_some() {
return self.noxtls_seal_server_tls12_chacha20_poly1305_record_packet(
plaintext,
content_type,
sequence,
suite,
);
}
let key = self
.server_write_key
.ok_or(Error::StateError("server write key is not installed"))?;
let iv = self
.server_write_iv
.ok_or(Error::StateError("server write iv is not installed"))?;
let explicit_nonce = sequence.to_be_bytes();
let nonce = Self::noxtls_build_tls12_aead_nonce(&iv, &explicit_nonce);
let aad = self.noxtls_build_tls12_record_aad(sequence, content_type, plaintext.len())?;
let (ciphertext, tag) =
Self::noxtls_aead_encrypt_for_suite(suite, &key, &nonce, &aad, plaintext)?;
let record = ProtectedRecord {
sequence,
ciphertext,
tag,
};
self.server_sequence = self.server_sequence.wrapping_add(1);
self.noxtls_encode_tls12_record_packet(&record, content_type, &explicit_nonce)
}
fn noxtls_open_client_tls12_cbc_record_packet(
&mut self,
packet: &[u8],
sequence: u64,
suite: CipherSuite,
) -> Result<(RecordContentType, Vec<u8>)> {
let (content_type_u8, version, payload) = noxtls_decode_tls12_ciphertext_record(packet)?;
let strict_version = noxtls_legacy_wire_version(self.version);
let legacy_compat_ok = self.tls12_allow_legacy_record_versions
&& (version == [0x03, 0x01] || version == [0x03, 0x02]);
if version != strict_version && !legacy_compat_ok {
return Err(Error::ParseFailure(
"tls12 record has invalid legacy version",
));
}
let content_type = RecordContentType::from_u8(content_type_u8)
.ok_or(Error::ParseFailure("unknown tls12 record content type"))?;
let key_len = suite.noxtls_tls12_cbc_key_len().ok_or(Error::StateError(
"tls 1.2 cbc suite must define traffic key length",
))?;
if payload.len() < 32 || (payload.len() - 16) % 16 != 0 {
return Err(Error::ParseFailure("invalid tls12 cbc record length"));
}
let mut explicit_iv = [0_u8; 16];
explicit_iv.copy_from_slice(&payload[..16]);
let key = self
.client_write_key
.ok_or(Error::StateError("client write key is not installed"))?;
let mac_key = self
.tls12_client_write_mac_key
.ok_or(Error::StateError("client write mac key is not installed"))?;
let cipher = AesCipher::noxtls_new(&key[..key_len])?;
let plaintext_mac_padding = noxtls_aes_cbc_decrypt(&cipher, &explicit_iv, &payload[16..])?;
let Some(&padding_len_u8) = plaintext_mac_padding.last() else {
return Err(Error::CryptoFailure("tls12 cbc record missing padding"));
};
let padding_total = usize::from(padding_len_u8) + 1;
let padding_invalid = if padding_total > plaintext_mac_padding.len() {
1_u8
} else {
let padding_start = plaintext_mac_padding.len() - padding_total;
let mut diff = 0_u8;
for byte in &plaintext_mac_padding[padding_start..] {
diff |= byte ^ padding_len_u8;
}
diff
};
let mac_len = 20_usize;
let mac_start = plaintext_mac_padding
.len()
.saturating_sub(padding_total)
.saturating_sub(mac_len);
let length_invalid = if mac_start + mac_len > plaintext_mac_padding.len()
|| padding_total > plaintext_mac_padding.len()
{
1_u8
} else {
0_u8
};
let plaintext = &plaintext_mac_padding[..mac_start];
let received_mac = if length_invalid == 0 {
&plaintext_mac_padding[mac_start..mac_start + mac_len]
} else {
&plaintext_mac_padding[..0]
};
let expected_mac =
Self::noxtls_tls12_cbc_hmac_sha1(&mac_key, sequence, content_type, plaintext)?;
let mac_invalid = if length_invalid == 0 {
u8::from(!noxtls_constant_time_eq(received_mac, &expected_mac))
} else {
1_u8
};
if padding_invalid != 0 || mac_invalid != 0 || length_invalid != 0 {
return Err(Error::CryptoFailure("tls12 cbc record mac mismatch"));
}
if plaintext.len() > self.max_record_plaintext_len {
return Err(Error::InvalidLength(
"record plaintext exceeds configured limit",
));
}
self.client_sequence = self.client_sequence.wrapping_add(1);
Ok((content_type, plaintext.to_vec()))
}
fn noxtls_seal_server_tls12_cbc_record_packet(
&mut self,
plaintext: &[u8],
content_type: RecordContentType,
sequence: u64,
suite: CipherSuite,
) -> Result<Vec<u8>> {
let key_len = suite.noxtls_tls12_cbc_key_len().ok_or(Error::StateError(
"tls 1.2 cbc suite must define traffic key length",
))?;
let key = self
.server_write_key
.ok_or(Error::StateError("server write key is not installed"))?;
let mac_key = self
.tls12_server_write_mac_key
.ok_or(Error::StateError("server write mac key is not installed"))?;
let mut explicit_iv = [0_u8; 16];
explicit_iv[..8].copy_from_slice(&sequence.to_be_bytes());
explicit_iv[8..].copy_from_slice(&(!sequence).to_be_bytes());
let mac = Self::noxtls_tls12_cbc_hmac_sha1(&mac_key, sequence, content_type, plaintext)?;
let mut plain = Vec::with_capacity(plaintext.len() + mac.len() + 16);
plain.extend_from_slice(plaintext);
plain.extend_from_slice(&mac);
let padding_len = 15 - (plain.len() % 16);
plain.extend(core::iter::repeat(padding_len as u8).take(padding_len + 1));
let cipher = AesCipher::noxtls_new(&key[..key_len])?;
let ciphertext = noxtls_aes_cbc_encrypt(&cipher, &explicit_iv, &plain)?;
let mut payload = Vec::with_capacity(16 + ciphertext.len());
payload.extend_from_slice(&explicit_iv);
payload.extend_from_slice(&ciphertext);
self.server_sequence = self.server_sequence.wrapping_add(1);
noxtls_encode_tls12_ciphertext_record(
content_type.to_u8(),
noxtls_legacy_wire_version(self.version),
&payload,
)
}
fn noxtls_tls12_cbc_hmac_sha1(
mac_key: &[u8; 20],
sequence: u64,
content_type: RecordContentType,
plaintext: &[u8],
) -> Result<[u8; 20]> {
if plaintext.len() > usize::from(u16::MAX) {
return Err(Error::InvalidLength(
"tls12 cbc plaintext length exceeds u16",
));
}
let mut mac_input = Vec::with_capacity(13 + plaintext.len());
mac_input.extend_from_slice(&sequence.to_be_bytes());
mac_input.push(content_type.to_u8());
mac_input.extend_from_slice(&[0x03, 0x03]);
mac_input.extend_from_slice(&(plaintext.len() as u16).to_be_bytes());
mac_input.extend_from_slice(plaintext);
Ok(noxtls_hmac_sha1(mac_key, &mac_input))
}
fn noxtls_open_client_tls12_chacha20_poly1305_record_packet(
&mut self,
packet: &[u8],
sequence: u64,
suite: CipherSuite,
) -> Result<(RecordContentType, Vec<u8>)> {
let (content_type_u8, version, payload) = noxtls_decode_tls12_ciphertext_record(packet)?;
let strict_version = noxtls_legacy_wire_version(self.version);
let legacy_compat_ok = self.tls12_allow_legacy_record_versions
&& (version == [0x03, 0x01] || version == [0x03, 0x02]);
if version != strict_version && !legacy_compat_ok {
return Err(Error::ParseFailure(
"tls12 record has invalid legacy version",
));
}
let content_type = RecordContentType::from_u8(content_type_u8)
.ok_or(Error::ParseFailure("unknown tls12 record content type"))?;
suite
.noxtls_tls12_chacha20_poly1305_key_len()
.ok_or(Error::StateError(
"tls 1.2 chacha20 suite must define traffic key length",
))?;
if payload.len() < 16 {
return Err(Error::ParseFailure(
"tls12 chacha20-poly1305 record payload too short",
));
}
let tag_offset = payload.len() - 16;
let ciphertext = &payload[..tag_offset];
let mut tag = [0_u8; 16];
tag.copy_from_slice(&payload[tag_offset..]);
let key = self
.client_write_key
.ok_or(Error::StateError("client write key is not installed"))?;
let iv = self
.client_write_iv
.ok_or(Error::StateError("client write iv is not installed"))?;
let nonce = Self::noxtls_build_tls12_chacha20_poly1305_nonce(&iv, sequence);
let aad = self.noxtls_build_tls12_record_aad(sequence, content_type, ciphertext.len())?;
let plaintext = noxtls_chacha20_poly1305_decrypt(&key, &nonce, &aad, ciphertext, &tag)?;
if plaintext.len() > self.max_record_plaintext_len {
return Err(Error::InvalidLength(
"record plaintext exceeds configured limit",
));
}
self.client_sequence = self.client_sequence.wrapping_add(1);
Ok((content_type, plaintext))
}
fn noxtls_seal_server_tls12_chacha20_poly1305_record_packet(
&mut self,
plaintext: &[u8],
content_type: RecordContentType,
sequence: u64,
suite: CipherSuite,
) -> Result<Vec<u8>> {
suite
.noxtls_tls12_chacha20_poly1305_key_len()
.ok_or(Error::StateError(
"tls 1.2 chacha20 suite must define traffic key length",
))?;
let key = self
.server_write_key
.ok_or(Error::StateError("server write key is not installed"))?;
let iv = self
.server_write_iv
.ok_or(Error::StateError("server write iv is not installed"))?;
let nonce = Self::noxtls_build_tls12_chacha20_poly1305_nonce(&iv, sequence);
let aad = self.noxtls_build_tls12_record_aad(sequence, content_type, plaintext.len())?;
let (ciphertext, tag) = noxtls_chacha20_poly1305_encrypt(&key, &nonce, &aad, plaintext)?;
let mut payload = Vec::with_capacity(ciphertext.len() + tag.len());
payload.extend_from_slice(&ciphertext);
payload.extend_from_slice(&tag);
self.server_sequence = self.server_sequence.wrapping_add(1);
noxtls_encode_tls12_ciphertext_record(
content_type.to_u8(),
noxtls_legacy_wire_version(self.version),
&payload,
)
}
pub(super) fn noxtls_build_tls12_chacha20_poly1305_nonce(
fixed_iv: &[u8; 12],
sequence: u64,
) -> [u8; 12] {
let mut padded_sequence = [0_u8; 12];
padded_sequence[4..].copy_from_slice(&sequence.to_be_bytes());
let mut nonce = [0_u8; 12];
for i in 0..12 {
nonce[i] = fixed_iv[i] ^ padded_sequence[i];
}
nonce
}
pub fn noxtls_seal_server_tls13_inner_record(
&mut self,
content: &[u8],
content_type: u8,
aad: &[u8],
padding_len: usize,
) -> Result<ProtectedRecord> {
if !self.version.uses_tls13_handshake_semantics() {
return Err(Error::StateError(
"tls13 inner plaintext records require TLS 1.3 connection",
));
}
let inner = noxtls_encode_tls13_inner_plaintext(content, content_type, padding_len);
self.noxtls_seal_server_record(&inner, aad)
}
pub fn noxtls_open_client_tls13_inner_record(
&mut self,
record: &ProtectedRecord,
aad: &[u8],
) -> Result<(Vec<u8>, u8)> {
if !self.version.uses_tls13_handshake_semantics() {
return Err(Error::StateError(
"tls13 inner plaintext records require TLS 1.3 connection",
));
}
let inner = self.noxtls_open_client_record(record, aad)?;
noxtls_decode_tls13_inner_plaintext(&inner)
}
pub fn noxtls_seal_server_tls13_record_packet(
&mut self,
content: &[u8],
content_type: u8,
aad: &[u8],
padding_len: usize,
) -> Result<Vec<u8>> {
if !self.version.uses_tls13_handshake_semantics() {
return Err(Error::StateError(
"tls13 record packets require TLS 1.3 connection",
));
}
let record =
self.noxtls_seal_server_tls13_inner_record(content, content_type, aad, padding_len)?;
self.noxtls_encode_tls13_record_packet(&record)
}
pub fn noxtls_open_client_tls13_record_packet(
&mut self,
packet: &[u8],
aad: &[u8],
) -> Result<(Vec<u8>, u8)> {
if !self.version.uses_tls13_handshake_semantics() {
return Err(Error::StateError(
"tls13 record packets require TLS 1.3 connection",
));
}
let record = self.noxtls_decode_tls13_record_packet(packet, self.client_sequence)?;
self.noxtls_open_client_tls13_inner_record(&record, aad)
}
pub(super) fn noxtls_aead_encrypt_for_suite(
suite: CipherSuite,
key: &[u8; 32],
nonce: &[u8; 12],
aad: &[u8],
plaintext: &[u8],
) -> Result<(Vec<u8>, [u8; 16])> {
match suite {
CipherSuite::TlsChacha20Poly1305Sha256 => {
noxtls_chacha20_poly1305_encrypt(key, nonce, aad, plaintext)
}
CipherSuite::TlsAes128GcmSha256 | CipherSuite::TlsAes256GcmSha384 => {
let key_len = suite
.noxtls_tls13_traffic_key_len()
.ok_or(Error::StateError(
"tls 1.3 aes suites must define traffic key length",
))?;
let cipher = AesCipher::noxtls_new(&key[..key_len])?;
noxtls_aes_gcm_encrypt(&cipher, nonce, aad, plaintext)
}
CipherSuite::TlsEcdheRsaWithAes128GcmSha256
| CipherSuite::TlsEcdheRsaWithAes256GcmSha384
| CipherSuite::TlsEcdheEcdsaWithAes128GcmSha256
| CipherSuite::TlsEcdheEcdsaWithAes256GcmSha384
| CipherSuite::TlsDheRsaWithAes128GcmSha256
| CipherSuite::TlsDheRsaWithAes256GcmSha384
| CipherSuite::TlsRsaWithAes128GcmSha256
| CipherSuite::TlsRsaWithAes256GcmSha384 => {
let key_len = suite.noxtls_tls12_aead_key_len().ok_or(Error::StateError(
"tls 1.2 aes-gcm suites must define traffic key length",
))?;
let cipher = AesCipher::noxtls_new(&key[..key_len])?;
noxtls_aes_gcm_encrypt(&cipher, nonce, aad, plaintext)
}
CipherSuite::TlsEcdheEcdsaWithAes128CcmSha256
| CipherSuite::TlsEcdheEcdsaWithAes256CcmSha256
| CipherSuite::TlsEcdheEcdsaWithAes128Ccm8Sha256
| CipherSuite::TlsEcdheEcdsaWithAes256Ccm8Sha256
| CipherSuite::TlsRsaWithAes128CcmSha256
| CipherSuite::TlsRsaWithAes256CcmSha256
| CipherSuite::TlsRsaWithAes128Ccm8Sha256
| CipherSuite::TlsRsaWithAes256Ccm8Sha256
| CipherSuite::TlsDheRsaWithAes128CcmSha256
| CipherSuite::TlsDheRsaWithAes256CcmSha256
| CipherSuite::TlsDheRsaWithAes128Ccm8Sha256
| CipherSuite::TlsDheRsaWithAes256Ccm8Sha256
| CipherSuite::TlsPskWithAes128Ccm8Sha256
| CipherSuite::TlsEcjpakeWithAes128Ccm8Sha256 => {
let key_len = suite.noxtls_tls12_aead_key_len().ok_or(Error::StateError(
"tls 1.2 aes-ccm suites must define traffic key length",
))?;
let tag_len = suite.noxtls_tls12_aead_tag_len().ok_or(Error::StateError(
"tls 1.2 aes-ccm suites must define tag length",
))?;
let cipher = AesCipher::noxtls_new(&key[..key_len])?;
noxtls_aes_ccm_encrypt_with_tag_len(&cipher, nonce, aad, plaintext, tag_len)
}
CipherSuite::TlsEcdheRsaWithAes128CbcSha | CipherSuite::TlsRsaWithAes128CbcSha => Err(
Error::UnsupportedFeature("tls 1.2 cbc uses block record protection"),
),
CipherSuite::TlsEcdheRsaWithChacha20Poly1305Sha256
| CipherSuite::TlsEcdheEcdsaWithChacha20Poly1305Sha256
| CipherSuite::TlsDheRsaWithChacha20Poly1305Sha256 => Err(Error::UnsupportedFeature(
"tls 1.2 chacha20-poly1305 uses tls12 nonce record protection",
)),
}
}
pub(super) fn noxtls_aead_decrypt_for_suite(
suite: CipherSuite,
key: &[u8; 32],
nonce: &[u8; 12],
aad: &[u8],
ciphertext: &[u8],
tag: &[u8; 16],
) -> Result<Vec<u8>> {
match suite {
CipherSuite::TlsChacha20Poly1305Sha256 => {
noxtls_chacha20_poly1305_decrypt(key, nonce, aad, ciphertext, tag)
}
CipherSuite::TlsAes128GcmSha256 | CipherSuite::TlsAes256GcmSha384 => {
let key_len = suite
.noxtls_tls13_traffic_key_len()
.ok_or(Error::StateError(
"tls 1.3 aes suites must define traffic key length",
))?;
let cipher = AesCipher::noxtls_new(&key[..key_len])?;
noxtls_aes_gcm_decrypt(&cipher, nonce, aad, ciphertext, tag)
}
CipherSuite::TlsEcdheRsaWithAes128GcmSha256
| CipherSuite::TlsEcdheRsaWithAes256GcmSha384
| CipherSuite::TlsEcdheEcdsaWithAes128GcmSha256
| CipherSuite::TlsEcdheEcdsaWithAes256GcmSha384
| CipherSuite::TlsDheRsaWithAes128GcmSha256
| CipherSuite::TlsDheRsaWithAes256GcmSha384
| CipherSuite::TlsRsaWithAes128GcmSha256
| CipherSuite::TlsRsaWithAes256GcmSha384 => {
let key_len = suite.noxtls_tls12_aead_key_len().ok_or(Error::StateError(
"tls 1.2 aes-gcm suites must define traffic key length",
))?;
let cipher = AesCipher::noxtls_new(&key[..key_len])?;
noxtls_aes_gcm_decrypt(&cipher, nonce, aad, ciphertext, tag)
}
CipherSuite::TlsEcdheEcdsaWithAes128CcmSha256
| CipherSuite::TlsEcdheEcdsaWithAes256CcmSha256
| CipherSuite::TlsEcdheEcdsaWithAes128Ccm8Sha256
| CipherSuite::TlsEcdheEcdsaWithAes256Ccm8Sha256
| CipherSuite::TlsRsaWithAes128CcmSha256
| CipherSuite::TlsRsaWithAes256CcmSha256
| CipherSuite::TlsRsaWithAes128Ccm8Sha256
| CipherSuite::TlsRsaWithAes256Ccm8Sha256
| CipherSuite::TlsDheRsaWithAes128CcmSha256
| CipherSuite::TlsDheRsaWithAes256CcmSha256
| CipherSuite::TlsDheRsaWithAes128Ccm8Sha256
| CipherSuite::TlsDheRsaWithAes256Ccm8Sha256
| CipherSuite::TlsPskWithAes128Ccm8Sha256
| CipherSuite::TlsEcjpakeWithAes128Ccm8Sha256 => {
let key_len = suite.noxtls_tls12_aead_key_len().ok_or(Error::StateError(
"tls 1.2 aes-ccm suites must define traffic key length",
))?;
let tag_len = suite.noxtls_tls12_aead_tag_len().ok_or(Error::StateError(
"tls 1.2 aes-ccm suites must define tag length",
))?;
let cipher = AesCipher::noxtls_new(&key[..key_len])?;
noxtls_aes_ccm_decrypt_with_tag_len(&cipher, nonce, aad, ciphertext, tag, tag_len)
}
CipherSuite::TlsEcdheRsaWithAes128CbcSha | CipherSuite::TlsRsaWithAes128CbcSha => Err(
Error::UnsupportedFeature("tls 1.2 cbc uses block record protection"),
),
CipherSuite::TlsEcdheRsaWithChacha20Poly1305Sha256
| CipherSuite::TlsEcdheEcdsaWithChacha20Poly1305Sha256
| CipherSuite::TlsDheRsaWithChacha20Poly1305Sha256 => Err(Error::UnsupportedFeature(
"tls 1.2 chacha20-poly1305 uses tls12 nonce record protection",
)),
}
}
}