AES-CCM cipher suites for rustls.
Neither aws-lc-rs nor ring expose AES-CCM, so rustls's built-in providers cannot offer these suites. This crate fills the gap using the RustCrypto aes + ccm crates, plugged in via rustls's CryptoProvider extension point.
CCM cipher suites are required or recommended by several IoT and energy protocols:
- IEEE 2030.5 (Smart Energy) — mandates
TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 - Matter / Thread — uses TLS 1.3
TLS_AES_128_CCM_SHA256 - RFC 7925 (constrained-device TLS) — profiles CCM and CCM-8 suites
- CoAP over DTLS — commonly uses CCM-8 for bandwidth efficiency
Without this crate, using rustls for these protocols requires falling back to OpenSSL or BoringSSL (which removed CCM entirely).
TLS 1.2 (RFC 7251)
| Suite | Tag | Key |
|---|---|---|
TLS_ECDHE_ECDSA_WITH_AES_128_CCM |
16 B | 128-bit |
TLS_ECDHE_ECDSA_WITH_AES_256_CCM |
16 B | 256-bit |
TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 |
8 B | 128-bit |
TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 |
8 B | 256-bit |
TLS 1.3 (RFC 8446)
| Suite | Tag | Key |
|---|---|---|
TLS_AES_128_CCM_SHA256 |
16 B | 128-bit |
TLS_AES_128_CCM_8_SHA256 |
8 B | 128-bit |
[dependencies]
rustls-ccm = "0.2"
rustls = "0.23"let provider = rustls_ccm::crypto_provider();
let config = rustls::ClientConfig::builder_with_provider(provider.into())
.with_safe_default_protocol_versions()
.unwrap();The CCM suites are appended after the provider defaults, so AES-GCM / ChaCha20-Poly1305 keep priority and CCM is negotiated only with peers that offer nothing stronger. To prefer CCM (e.g. for a profile that mandates it), put the suites you want in front, as below.
use rustls::crypto::CryptoProvider;
let mut provider = rustls::crypto::aws_lc_rs::default_provider();
provider.cipher_suites.insert(0, *rustls_ccm::TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
let config = rustls::ClientConfig::builder_with_provider(provider.into())
.with_safe_default_protocol_versions()
.unwrap();- Raw traffic-secret extraction for kTLS/hardware offload (
dangerous_extract_secrets()) is not supported — rustls'sConnectionTrafficSecretshas no CCM variant, soextract_keysreturnsUnsupportedOperationErrorfor all CCM suites.SSLKEYLOGFILE-style key logging (rustls::KeyLog) is unaffected and works normally.
The crate borrows key exchange (ECDHE), signature (ECDSA), hash (SHA-256), PRF, and HKDF implementations from the aws-lc-rs provider. Only the AEAD algorithm is replaced with a CCM implementation built on RustCrypto's aes and ccm crates.
cargo test runs loopback handshake tests for every suite, plus
interoperability tests against openssl s_server covering all six suites in
both record directions. The interop tests need an OpenSSL 3.x binary
(openssl on PATH, a Homebrew openssl@3 install, or the OPENSSL env
var) and are skipped with a notice when none is found — macOS's bundled
LibreSSL does not support the CCM suites.
MIT OR Apache-2.0