diff --git a/.gitignore b/.gitignore index c8e9e48..636e67c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target Cargo.lock .vscode +.embuild diff --git a/Cargo.toml b/Cargo.toml index 268671d..f785efa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,3 +2,11 @@ members = ["matter", "matter_macro_derive", "tools/tlv_tool"] exclude = ["examples/*"] + +# For compatibility with ESP IDF +[patch.crates-io] +smol = { git = "https://github.com/esp-rs-compat/smol" } +polling = { git = "https://github.com/esp-rs-compat/polling" } +socket2 = { git = "https://github.com/esp-rs-compat/socket2" } +chrono = { git = "https://github.com/ivmarkov/chrono" } +time = { git = "https://github.com/ivmarkov/time", branch = "master" } diff --git a/matter/Cargo.toml b/matter/Cargo.toml index 8c4179a..a1f0840 100644 --- a/matter/Cargo.toml +++ b/matter/Cargo.toml @@ -16,13 +16,12 @@ path = "src/lib.rs" [features] default = ["std", "crypto_mbedtls", "backtrace"] -std = ["alloc", "env_logger", "chrono", "rand", "qrcode", "libmdns", "simple-mdns", "simple-dns", "smol"] +std = ["alloc", "env_logger", "chrono", "time", "rand", "qrcode", "libmdns", "simple-mdns", "simple-dns", "async-io", "smol"] backtrace = [] alloc = [] nightly = [] crypto_openssl = ["alloc", "openssl", "foreign-types", "hmac", "sha2"] -crypto_mbedtls = ["alloc", "mbedtls"] -crypto_esp_mbedtls = ["esp-idf-sys"] +crypto_mbedtls = ["alloc", "mbedtls", "esp-idf-sys"] crypto_rustcrypto = ["alloc", "sha2", "hmac", "pbkdf2", "hkdf", "aes", "ccm", "p256", "elliptic-curve", "crypto-bigint", "x509-cert", "rand_core"] [dependencies] @@ -39,23 +38,22 @@ no-std-net = "0.6" subtle = "2.4.1" safemem = "0.3.3" owo-colors = "3" +verhoeff = { version = "1", default-features = false } # STD-only dependencies -env_logger = { version = "0.10.0", default-features = false, optional = true } -chrono = { version = "0.4.23", optional = true, default-features = false, features = ["clock", "std"] } +chrono = { version = "=0.4.19", optional = true, default-features = false, features = ["clock", "std"] } # =0.4.19 for compatibility with ESP IDF +time = { version = "0.1", optional = true, default-features = false } rand = { version = "0.8.5", optional = true } qrcode = { version = "0.12", default-features = false, optional = true } # Print QR code -libmdns = { version = "0.7", optional = true } simple-mdns = { version = "0.4", features = ["sync"], optional = true } simple-dns = { version = "0.5", optional = true } astro-dnssd = { version = "0.3", optional = true } # On Linux needs avahi-compat-libdns_sd, i.e. on Ubuntu/Debian do `sudo apt-get install libavahi-compat-libdnssd-dev` zeroconf = { version = "0.10", optional = true } -smol = { version = "1.3.0", optional = true} +smol = { version = "1.2", optional = true } # =1.2 for compatibility with ESP IDF +async-io = { version = "=1.12", optional = true } # =1.2 for compatibility with ESP IDF # crypto openssl = { git = "https://github.com/sfackler/rust-openssl", optional = true } -mbedtls = { git = "https://github.com/fortanix/rust-mbedtls", optional = true } -esp-idf-sys = { version = "0.32", optional = true } # rust-crypto foreign-types = { version = "0.3.2", optional = true } @@ -71,8 +69,13 @@ crypto-bigint = { version = "0.4", default-features = false, optional = true } rand_core = { version = "0.6", default-features = false, optional = true } x509-cert = { version = "0.2.0", default-features = false, features = ["pem"], optional = true } # TODO: requires `alloc` -# to compute the check digit -verhoeff = "1" +[target.'cfg(not(target_os = "espidf"))'.dependencies] +mbedtls = { git = "https://github.com/fortanix/rust-mbedtls", optional = true } +env_logger = { version = "0.10.0", optional = true } +libmdns = { version = "0.7", optional = true } + +[target.'cfg(target_os = "espidf")'.dependencies] +esp-idf-sys = { version = "0.32", default-features = false, features = ["native"], optional = true } [[example]] name = "onoff_light" diff --git a/matter/src/crypto/crypto_esp_mbedtls.rs b/matter/src/crypto/crypto_esp_mbedtls.rs index cad046b..2fff707 100644 --- a/matter/src/crypto/crypto_esp_mbedtls.rs +++ b/matter/src/crypto/crypto_esp_mbedtls.rs @@ -18,6 +18,7 @@ use log::error; use crate::error::{Error, ErrorCode}; +use crate::utils::rand::Rand; pub fn hkdf_sha256(_salt: &[u8], _ikm: &[u8], _info: &[u8], _key: &mut [u8]) -> Result<(), Error> { error!("This API should never get called"); @@ -60,10 +61,11 @@ impl HmacSha256 { } } +#[derive(Debug)] pub struct KeyPair {} impl KeyPair { - pub fn new() -> Result { + pub fn new(_rand: Rand) -> Result { error!("This API should never get called"); Ok(Self {}) diff --git a/matter/src/crypto/mod.rs b/matter/src/crypto/mod.rs index 47d49b7..85c40b0 100644 --- a/matter/src/crypto/mod.rs +++ b/matter/src/crypto/mod.rs @@ -37,14 +37,14 @@ pub const ECDH_SHARED_SECRET_LEN_BYTES: usize = 32; pub const EC_SIGNATURE_LEN_BYTES: usize = 64; -#[cfg(feature = "crypto_esp_mbedtls")] +#[cfg(all(feature = "crypto_mbedtls", target_os = "espidf"))] mod crypto_esp_mbedtls; -#[cfg(feature = "crypto_esp_mbedtls")] +#[cfg(all(feature = "crypto_mbedtls", target_os = "espidf"))] pub use self::crypto_esp_mbedtls::*; -#[cfg(feature = "crypto_mbedtls")] +#[cfg(all(feature = "crypto_mbedtls", not(target_os = "espidf")))] mod crypto_mbedtls; -#[cfg(feature = "crypto_mbedtls")] +#[cfg(all(feature = "crypto_mbedtls", not(target_os = "espidf")))] pub use self::crypto_mbedtls::*; #[cfg(feature = "crypto_openssl")] @@ -60,14 +60,12 @@ pub use self::crypto_rustcrypto::*; #[cfg(not(any( feature = "crypto_openssl", feature = "crypto_mbedtls", - feature = "crypto_esp_mbedtls", feature = "crypto_rustcrypto" )))] pub mod crypto_dummy; #[cfg(not(any( feature = "crypto_openssl", feature = "crypto_mbedtls", - feature = "crypto_esp_mbedtls", feature = "crypto_rustcrypto" )))] pub use self::crypto_dummy::*; diff --git a/matter/src/error.rs b/matter/src/error.rs index 507ce4b..e15cbb7 100644 --- a/matter/src/error.rs +++ b/matter/src/error.rs @@ -157,7 +157,7 @@ impl From for Error { } } -#[cfg(feature = "crypto_mbedtls")] +#[cfg(all(feature = "crypto_mbedtls", not(target_os = "espidf")))] impl From for Error { fn from(e: mbedtls::Error) -> Self { ::log::error!("Error in TLS: {}", e); @@ -165,6 +165,14 @@ impl From for Error { } } +#[cfg(all(feature = "crypto_mbedtls", target_os = "espidf"))] +impl From for Error { + fn from(e: esp_idf_sys::EspError) -> Self { + ::log::error!("Error in TLS: {}", e); + Self::new(ErrorCode::TLSStack) + } +} + #[cfg(feature = "crypto_rustcrypto")] impl From for Error { fn from(_e: ccm::aead::Error) -> Self { diff --git a/matter/src/mdns.rs b/matter/src/mdns.rs index eb19a9f..defb137 100644 --- a/matter/src/mdns.rs +++ b/matter/src/mdns.rs @@ -475,7 +475,7 @@ pub mod astro { // } // } -#[cfg(feature = "std")] +#[cfg(all(feature = "std", not(target_os = "espidf")))] pub mod libmdns { use super::Mdns; use crate::error::Error; diff --git a/matter/src/secure_channel/crypto.rs b/matter/src/secure_channel/crypto.rs index d1292eb..027db69 100644 --- a/matter/src/secure_channel/crypto.rs +++ b/matter/src/secure_channel/crypto.rs @@ -18,13 +18,12 @@ #[cfg(not(any( feature = "crypto_openssl", feature = "crypto_mbedtls", - feature = "crypto_esp_mbedtls", feature = "crypto_rustcrypto" )))] pub use super::crypto_dummy::CryptoSpake2; -#[cfg(feature = "crypto_esp_mbedtls")] +#[cfg(all(feature = "crypto_mbedtls", target_os = "espidf"))] pub use super::crypto_esp_mbedtls::CryptoSpake2; -#[cfg(feature = "crypto_mbedtls")] +#[cfg(all(feature = "crypto_mbedtls", not(target_os = "espidf")))] pub use super::crypto_mbedtls::CryptoSpake2; #[cfg(feature = "crypto_openssl")] pub use super::crypto_openssl::CryptoSpake2; diff --git a/matter/src/secure_channel/crypto_esp_mbedtls.rs b/matter/src/secure_channel/crypto_esp_mbedtls.rs index 316276b..d1d77ee 100644 --- a/matter/src/secure_channel/crypto_esp_mbedtls.rs +++ b/matter/src/secure_channel/crypto_esp_mbedtls.rs @@ -16,6 +16,7 @@ */ use crate::error::Error; +use crate::utils::rand::Rand; const MATTER_M_BIN: [u8; 65] = [ 0x04, 0x88, 0x6e, 0x2f, 0x97, 0xac, 0xe4, 0x6e, 0x55, 0xba, 0x9d, 0xd7, 0x24, 0x25, 0x79, 0xf2, @@ -77,7 +78,16 @@ impl CryptoSpake2 { } #[allow(non_snake_case)] - pub fn get_pB(&mut self, pB: &mut [u8]) -> Result<(), Error> { + #[allow(dead_code)] + pub fn set_L_from_w1s(&mut self, w1s: &[u8]) -> Result<(), Error> { + // From the Matter spec, + // L = w1 * P + // where P is the generator of the underlying elliptic curve + Ok(()) + } + + #[allow(non_snake_case)] + pub fn get_pB(&mut self, pB: &mut [u8], _rand: Rand) -> Result<(), Error> { // From the SPAKE2+ spec (https://datatracker.ietf.org/doc/draft-bar-cfrg-spake2plus/) // for y // - select random y between 0 to p diff --git a/matter/src/secure_channel/mod.rs b/matter/src/secure_channel/mod.rs index 15417b3..58020b4 100644 --- a/matter/src/secure_channel/mod.rs +++ b/matter/src/secure_channel/mod.rs @@ -20,13 +20,12 @@ pub mod common; #[cfg(not(any( feature = "crypto_openssl", feature = "crypto_mbedtls", - feature = "crypto_esp_mbedtls", feature = "crypto_rustcrypto" )))] mod crypto_dummy; -#[cfg(feature = "crypto_esp_mbedtls")] +#[cfg(all(feature = "crypto_mbedtls", target_os = "espidf"))] mod crypto_esp_mbedtls; -#[cfg(feature = "crypto_mbedtls")] +#[cfg(all(feature = "crypto_mbedtls", not(target_os = "espidf")))] mod crypto_mbedtls; #[cfg(feature = "crypto_openssl")] pub mod crypto_openssl; diff --git a/matter/tests/common/mod.rs b/matter/tests/common/mod.rs index 96682b9..94837fc 100644 --- a/matter/tests/common/mod.rs +++ b/matter/tests/common/mod.rs @@ -22,7 +22,7 @@ pub mod handlers; pub mod im_engine; pub fn init_env_logger() { - #[cfg(feature = "std")] + #[cfg(all(feature = "std", not(target_os = "espidf")))] { let _ = env_logger::try_init(); }