From 2f2e332c75dd02c62258e4b2f148cbb38a4a92a7 Mon Sep 17 00:00:00 2001 From: ivmarkov Date: Thu, 4 May 2023 05:42:58 +0000 Subject: [PATCH] Fix compilation errors in crypto --- matter/Cargo.toml | 12 +-- matter/src/cert/mod.rs | 1 - matter/src/crypto/crypto_dummy.rs | 8 +- matter/src/crypto/crypto_mbedtls.rs | 3 +- matter/src/crypto/crypto_openssl.rs | 15 +++- matter/src/crypto/crypto_rustcrypto.rs | 33 ++++--- matter/src/data_model/sdm/noc.rs | 4 +- matter/src/pairing/qr.rs | 1 + matter/src/secure_channel/case.rs | 2 +- matter/src/secure_channel/crypto.rs | 5 +- matter/src/secure_channel/crypto_dummy.rs | 7 +- matter/src/secure_channel/crypto_mbedtls.rs | 7 +- matter/src/secure_channel/crypto_openssl.rs | 9 +- .../src/secure_channel/crypto_rustcrypto.rs | 88 ++++++++++++------- matter/src/secure_channel/pake.rs | 2 +- matter/src/secure_channel/spake2p.rs | 10 ++- matter/src/transport/network.rs | 4 +- 17 files changed, 139 insertions(+), 72 deletions(-) diff --git a/matter/Cargo.toml b/matter/Cargo.toml index ba65b02..4eb2a74 100644 --- a/matter/Cargo.toml +++ b/matter/Cargo.toml @@ -20,10 +20,10 @@ std = ["alloc", "env_logger", "chrono", "rand", "qrcode", "libmdns", "simple-mdn backtrace = [] alloc = [] nightly = [] -crypto_openssl = ["openssl", "foreign-types", "hmac", "sha2"] -crypto_mbedtls = ["mbedtls", "alloc"] +crypto_openssl = ["alloc", "openssl", "foreign-types", "hmac", "sha2"] +crypto_mbedtls = ["alloc", "mbedtls"] crypto_esp_mbedtls = ["esp-idf-sys"] -crypto_rustcrypto = ["sha2", "hmac", "pbkdf2", "hkdf", "aes", "ccm", "p256", "elliptic-curve", "crypto-bigint", "x509-cert"] +crypto_rustcrypto = ["alloc", "sha2", "hmac", "pbkdf2", "hkdf", "aes", "ccm", "p256", "elliptic-curve", "crypto-bigint", "x509-cert", "rand_core"] [dependencies] matter_macro_derive = { path = "../matter_macro_derive" } @@ -56,6 +56,8 @@ smol = { version = "1.3.0", optional = true} 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 } sha2 = { version = "0.10", default-features = false, optional = true } hmac = { version = "0.12", optional = true } @@ -66,8 +68,8 @@ ccm = { version = "0.5", default-features = false, features = ["alloc"], optiona p256 = { version = "0.13.0", default-features = false, features = ["arithmetic", "ecdh", "ecdsa"], optional = true } elliptic-curve = { version = "0.13.2", optional = true } crypto-bigint = { version = "0.4", default-features = false, optional = true } -# TODO: requires STD -x509-cert = { version = "0.2.0", default-features = false, features = ["pem", "std"], optional = true } +rand_core = { version = "0.6", default-features = false, optional = true } +x509-cert = { version = "0.2.0", default-features = false, features = ["pem", "std"], optional = true } # TODO: requires `alloc` # to compute the check digit verhoeff = "1" diff --git a/matter/src/cert/mod.rs b/matter/src/cert/mod.rs index d750db5..0ec6dd5 100644 --- a/matter/src/cert/mod.rs +++ b/matter/src/cert/mod.rs @@ -859,7 +859,6 @@ mod tests { #[test] fn test_tlv_conversions() { - let _ = env_logger::try_init(); let test_input: [&[u8]; 3] = [ &test_vectors::NOC1_SUCCESS, &test_vectors::ICAC1_SUCCESS, diff --git a/matter/src/crypto/crypto_dummy.rs b/matter/src/crypto/crypto_dummy.rs index f00cefd..827b7f3 100644 --- a/matter/src/crypto/crypto_dummy.rs +++ b/matter/src/crypto/crypto_dummy.rs @@ -17,7 +17,10 @@ use log::error; -use crate::error::{Error, ErrorCode}; +use crate::{ + error::{Error, ErrorCode}, + 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 +63,11 @@ impl HmacSha256 { } } +#[derive(Debug)] pub struct KeyPair; impl KeyPair { - pub fn new() -> Result { + pub fn new(_rand: Rand) -> Result { Ok(Self) } diff --git a/matter/src/crypto/crypto_mbedtls.rs b/matter/src/crypto/crypto_mbedtls.rs index 3f95d04..1eb7a88 100644 --- a/matter/src/crypto/crypto_mbedtls.rs +++ b/matter/src/crypto/crypto_mbedtls.rs @@ -35,6 +35,7 @@ use crate::{ // so Crypto doesn't have to depend on Cert cert::{ASN1Writer, CertConsumer}, error::{Error, ErrorCode}, + utils::rand::Rand, }; pub struct HmacSha256 { @@ -65,7 +66,7 @@ pub struct KeyPair { } impl KeyPair { - pub fn new() -> Result { + pub fn new(_rand: Rand) -> Result { let mut ctr_drbg = CtrDrbg::new(Arc::new(OsEntropy::new()), None)?; Ok(Self { key: Pk::generate_ec(&mut ctr_drbg, EcGroupId::SecP256R1)?, diff --git a/matter/src/crypto/crypto_openssl.rs b/matter/src/crypto/crypto_openssl.rs index 5343c52..24fa267 100644 --- a/matter/src/crypto/crypto_openssl.rs +++ b/matter/src/crypto/crypto_openssl.rs @@ -16,7 +16,9 @@ */ use crate::error::{Error, ErrorCode}; +use crate::utils::rand::Rand; +use alloc::vec; use foreign_types::ForeignTypeRef; use log::error; use openssl::asn1::Asn1Type; @@ -39,6 +41,9 @@ use openssl::x509::{X509NameBuilder, X509ReqBuilder, X509}; // problem while using OpenSSL's Signer // TODO: Use proper OpenSSL method for this use hmac::{Hmac, Mac}; + +extern crate alloc; + pub struct HmacSha256 { ctx: Hmac, } @@ -62,16 +67,18 @@ impl HmacSha256 { } } +#[derive(Debug)] pub enum KeyType { Public(EcKey), Private(EcKey), } +#[derive(Debug)] pub struct KeyPair { key: KeyType, } impl KeyPair { - pub fn new() -> Result { + pub fn new(_rand: Rand) -> Result { let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1)?; let key = EcKey::generate(&group)?; Ok(Self { @@ -206,7 +213,7 @@ impl KeyPair { KeyType::Public(key) => key, _ => { error!("Not yet supported"); - Err(ErrorCode::Invalid)?; + return Err(ErrorCode::Invalid.into()); } }; if !sig.verify(&msg, k)? { @@ -293,7 +300,7 @@ pub fn lowlevel_encrypt_aead( aad: &[u8], data: &[u8], tag: &mut [u8], -) -> Result, ErrorStack> { +) -> Result, ErrorStack> { let t = symm::Cipher::aes_128_ccm(); let mut ctx = CipherCtx::new()?; CipherCtxRef::encrypt_init( @@ -329,7 +336,7 @@ pub fn lowlevel_decrypt_aead( aad: &[u8], data: &[u8], tag: &[u8], -) -> Result, ErrorStack> { +) -> Result, ErrorStack> { let t = symm::Cipher::aes_128_ccm(); let mut ctx = CipherCtx::new()?; CipherCtxRef::decrypt_init( diff --git a/matter/src/crypto/crypto_rustcrypto.rs b/matter/src/crypto/crypto_rustcrypto.rs index b9aa310..6f975cb 100644 --- a/matter/src/crypto/crypto_rustcrypto.rs +++ b/matter/src/crypto/crypto_rustcrypto.rs @@ -15,9 +15,10 @@ * limitations under the License. */ -use std::convert::{TryFrom, TryInto}; +use core::convert::{TryFrom, TryInto}; use aes::Aes128; +use alloc::vec; use ccm::{ aead::generic_array::GenericArray, consts::{U13, U16}, @@ -39,13 +40,17 @@ use x509_cert::{ spki::{AlgorithmIdentifier, SubjectPublicKeyInfoOwned}, }; -use crate::error::{Error, ErrorCode}; - -use super::CryptoKeyPair; +use crate::{ + error::{Error, ErrorCode}, + secure_channel::crypto_rustcrypto::RandRngCore, + utils::rand::Rand, +}; type HmacSha256I = hmac::Hmac; type AesCcm = Ccm; +extern crate alloc; + #[derive(Clone)] pub struct Sha256 { hasher: sha2::Sha256, @@ -96,18 +101,20 @@ impl HmacSha256 { } } +#[derive(Debug)] pub enum KeyType { Private(SecretKey), Public(PublicKey), } +#[derive(Debug)] pub struct KeyPair { key: KeyType, } impl KeyPair { - pub fn new() -> Result { - let mut rng = rand::thread_rng(); + pub fn new(rand: Rand) -> Result { + let mut rng = RandRngCore(rand); let secret_key = SecretKey::random(&mut rng); Ok(Self { @@ -146,10 +153,8 @@ impl KeyPair { KeyType::Public(_) => Err(ErrorCode::Crypto.into()), } } -} -impl CryptoKeyPair for KeyPair { - fn get_private_key(&self, priv_key: &mut [u8]) -> Result { + pub fn get_private_key(&self, priv_key: &mut [u8]) -> Result { match &self.key { KeyType::Private(key) => { let bytes = key.to_bytes(); @@ -161,7 +166,7 @@ impl CryptoKeyPair for KeyPair { KeyType::Public(_) => Err(ErrorCode::Crypto.into()), } } - fn get_csr<'a>(&self, out_csr: &'a mut [u8]) -> Result<&'a [u8], Error> { + pub fn get_csr<'a>(&self, out_csr: &'a mut [u8]) -> Result<&'a [u8], Error> { use p256::ecdsa::signature::Signer; let subject = RdnSequence(vec![x509_cert::name::RelativeDistinguishedName( @@ -224,14 +229,14 @@ impl CryptoKeyPair for KeyPair { Ok(a) } - fn get_public_key(&self, pub_key: &mut [u8]) -> Result { + pub fn get_public_key(&self, pub_key: &mut [u8]) -> Result { let point = self.public_key_point().to_encoded_point(false); let bytes = point.as_bytes(); let len = bytes.len(); pub_key[..len].copy_from_slice(bytes); Ok(len) } - fn derive_secret(self, peer_pub_key: &[u8], secret: &mut [u8]) -> Result { + pub fn derive_secret(self, peer_pub_key: &[u8], secret: &mut [u8]) -> Result { let encoded_point = EncodedPoint::from_bytes(peer_pub_key).unwrap(); let peer_pubkey = PublicKey::from_encoded_point(&encoded_point).unwrap(); let private_key = self.private_key()?; @@ -247,7 +252,7 @@ impl CryptoKeyPair for KeyPair { Ok(len) } - fn sign_msg(&self, msg: &[u8], signature: &mut [u8]) -> Result { + pub fn sign_msg(&self, msg: &[u8], signature: &mut [u8]) -> Result { use p256::ecdsa::signature::Signer; if signature.len() < super::EC_SIGNATURE_LEN_BYTES { @@ -266,7 +271,7 @@ impl CryptoKeyPair for KeyPair { KeyType::Public(_) => todo!(), } } - fn verify_msg(&self, msg: &[u8], signature: &[u8]) -> Result<(), Error> { + pub fn verify_msg(&self, msg: &[u8], signature: &[u8]) -> Result<(), Error> { use p256::ecdsa::signature::Verifier; let verifying_key = VerifyingKey::from_affine(self.public_key_point()).unwrap(); diff --git a/matter/src/data_model/sdm/noc.rs b/matter/src/data_model/sdm/noc.rs index 6182c0c..f7346cc 100644 --- a/matter/src/data_model/sdm/noc.rs +++ b/matter/src/data_model/sdm/noc.rs @@ -217,6 +217,7 @@ struct RemoveFabricReq { pub struct NocCluster<'a> { data_ver: Dataver, epoch: Epoch, + rand: Rand, dev_att: &'a dyn DevAttDataFetcher, fabric_mgr: &'a RefCell, acl_mgr: &'a RefCell, @@ -237,6 +238,7 @@ impl<'a> NocCluster<'a> { Self { data_ver: Dataver::new(rand), epoch, + rand, dev_att, fabric_mgr, acl_mgr, @@ -566,7 +568,7 @@ impl<'a> NocCluster<'a> { Err(ErrorCode::UnsupportedAccess)?; } - let noc_keypair = KeyPair::new()?; + let noc_keypair = KeyPair::new(self.rand)?; let mut attest_challenge = [0u8; crypto::SYMM_KEY_LEN_BYTES]; attest_challenge.copy_from_slice(transaction.session().get_att_challenge()); diff --git a/matter/src/pairing/qr.rs b/matter/src/pairing/qr.rs index 3550dfb..bb001ae 100644 --- a/matter/src/pairing/qr.rs +++ b/matter/src/pairing/qr.rs @@ -350,6 +350,7 @@ pub fn compute_qr_code<'a>( payload_base38_representation(&qr_code_data, buf) } +#[cfg(feature = "std")] fn compute_qr_version(qr_data: &str) -> i16 { match qr_data.len() { 0..=38 => 2, diff --git a/matter/src/secure_channel/case.rs b/matter/src/secure_channel/case.rs index 18011c9..3fa9249 100644 --- a/matter/src/secure_channel/case.rs +++ b/matter/src/secure_channel/case.rs @@ -213,7 +213,7 @@ impl<'a> Case<'a> { ); // Create an ephemeral Key Pair - let key_pair = KeyPair::new()?; + let key_pair = KeyPair::new(self.rand)?; let _ = key_pair.get_public_key(&mut case_session.our_pub_key)?; // Derive the Shared Secret diff --git a/matter/src/secure_channel/crypto.rs b/matter/src/secure_channel/crypto.rs index 45d8359..d1292eb 100644 --- a/matter/src/secure_channel/crypto.rs +++ b/matter/src/secure_channel/crypto.rs @@ -18,7 +18,8 @@ #[cfg(not(any( feature = "crypto_openssl", feature = "crypto_mbedtls", - feature = "crypto_esp_mbedtls" + feature = "crypto_esp_mbedtls", + feature = "crypto_rustcrypto" )))] pub use super::crypto_dummy::CryptoSpake2; #[cfg(feature = "crypto_esp_mbedtls")] @@ -27,3 +28,5 @@ pub use super::crypto_esp_mbedtls::CryptoSpake2; pub use super::crypto_mbedtls::CryptoSpake2; #[cfg(feature = "crypto_openssl")] pub use super::crypto_openssl::CryptoSpake2; +#[cfg(feature = "crypto_rustcrypto")] +pub use super::crypto_rustcrypto::CryptoSpake2; diff --git a/matter/src/secure_channel/crypto_dummy.rs b/matter/src/secure_channel/crypto_dummy.rs index 3933e79..414076e 100644 --- a/matter/src/secure_channel/crypto_dummy.rs +++ b/matter/src/secure_channel/crypto_dummy.rs @@ -15,7 +15,10 @@ * limitations under the License. */ -use crate::error::{Error, ErrorCode}; +use crate::{ + error::{Error, ErrorCode}, + utils::rand::Rand, +}; #[allow(non_snake_case)] @@ -56,7 +59,7 @@ impl CryptoSpake2 { } #[allow(non_snake_case)] - pub fn get_pB(&mut self, _pB: &mut [u8]) -> Result<(), Error> { + pub fn get_pB(&mut self, _pB: &mut [u8], _rand: Rand) -> Result<(), Error> { Err(ErrorCode::Invalid.into()) } diff --git a/matter/src/secure_channel/crypto_mbedtls.rs b/matter/src/secure_channel/crypto_mbedtls.rs index de7ea48..8ddec40 100644 --- a/matter/src/secure_channel/crypto_mbedtls.rs +++ b/matter/src/secure_channel/crypto_mbedtls.rs @@ -18,7 +18,10 @@ use alloc::sync::Arc; use core::ops::{Mul, Sub}; -use crate::error::{Error, ErrorCode}; +use crate::{ + error::{Error, ErrorCode}, + utils::rand::Rand, +}; use byteorder::{ByteOrder, LittleEndian}; use log::error; @@ -132,7 +135,7 @@ impl CryptoSpake2 { } #[allow(non_snake_case)] - pub fn get_pB(&mut self, pB: &mut [u8]) -> Result<(), Error> { + 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/crypto_openssl.rs b/matter/src/secure_channel/crypto_openssl.rs index de60fff..dd4f8b1 100644 --- a/matter/src/secure_channel/crypto_openssl.rs +++ b/matter/src/secure_channel/crypto_openssl.rs @@ -15,7 +15,10 @@ * limitations under the License. */ -use crate::error::{Error, ErrorCode}; +use crate::{ + error::{Error, ErrorCode}, + utils::rand::Rand, +}; use byteorder::{ByteOrder, LittleEndian}; use log::error; @@ -116,6 +119,7 @@ impl CryptoSpake2 { Ok(()) } + #[allow(non_snake_case)] pub fn set_L(&mut self, l: &[u8]) -> Result<(), Error> { self.L = EcPoint::from_bytes(&self.group, l, &mut self.bn_ctx)?; Ok(()) @@ -134,7 +138,7 @@ impl CryptoSpake2 { } #[allow(non_snake_case)] - pub fn get_pB(&mut self, pB: &mut [u8]) -> Result<(), Error> { + 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 @@ -331,7 +335,6 @@ impl CryptoSpake2 { mod tests { use super::CryptoSpake2; - use crate::secure_channel::crypto::CryptoSpake2; use crate::secure_channel::spake2p_test_vectors::test_vectors::*; use openssl::bn::BigNum; use openssl::ec::{EcPoint, PointConversionForm}; diff --git a/matter/src/secure_channel/crypto_rustcrypto.rs b/matter/src/secure_channel/crypto_rustcrypto.rs index a3ec628..2c1e50a 100644 --- a/matter/src/secure_channel/crypto_rustcrypto.rs +++ b/matter/src/secure_channel/crypto_rustcrypto.rs @@ -21,11 +21,12 @@ use elliptic_curve::ops::*; use elliptic_curve::sec1::{FromEncodedPoint, ToEncodedPoint}; use elliptic_curve::Field; use elliptic_curve::PrimeField; +use rand_core::CryptoRng; +use rand_core::RngCore; use sha2::Digest; use crate::error::Error; - -use super::crypto::CryptoSpake2; +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, @@ -44,7 +45,7 @@ const MATTER_N_BIN: [u8; 65] = [ #[allow(non_snake_case)] -pub struct CryptoRustCrypto { +pub struct CryptoSpake2 { xy: p256::Scalar, w0: p256::Scalar, w1: p256::Scalar, @@ -54,15 +55,15 @@ pub struct CryptoRustCrypto { pB: p256::EncodedPoint, } -impl CryptoSpake2 for CryptoRustCrypto { +impl CryptoSpake2 { #[allow(non_snake_case)] - fn new() -> Result { + pub fn new() -> Result { let M = p256::EncodedPoint::from_bytes(MATTER_M_BIN).unwrap(); let N = p256::EncodedPoint::from_bytes(MATTER_N_BIN).unwrap(); let L = p256::EncodedPoint::default(); let pB = p256::EncodedPoint::default(); - Ok(CryptoRustCrypto { + Ok(Self { xy: p256::Scalar::ZERO, w0: p256::Scalar::ZERO, w1: p256::Scalar::ZERO, @@ -74,7 +75,7 @@ impl CryptoSpake2 for CryptoRustCrypto { } // Computes w0 from w0s respectively - fn set_w0_from_w0s(&mut self, w0s: &[u8]) -> Result<(), Error> { + pub fn set_w0_from_w0s(&mut self, w0s: &[u8]) -> Result<(), Error> { // From the Matter Spec, // w0 = w0s mod p // where p is the order of the curve @@ -103,7 +104,7 @@ impl CryptoSpake2 for CryptoRustCrypto { Ok(()) } - fn set_w1_from_w1s(&mut self, w1s: &[u8]) -> Result<(), Error> { + pub fn set_w1_from_w1s(&mut self, w1s: &[u8]) -> Result<(), Error> { // From the Matter Spec, // w1 = w1s mod p // where p is the order of the curve @@ -132,14 +133,14 @@ impl CryptoSpake2 for CryptoRustCrypto { Ok(()) } - fn set_w0(&mut self, w0: &[u8]) -> Result<(), Error> { + pub fn set_w0(&mut self, w0: &[u8]) -> Result<(), Error> { self.w0 = p256::Scalar::from_repr(*elliptic_curve::generic_array::GenericArray::from_slice(w0)) .unwrap(); Ok(()) } - fn set_w1(&mut self, w1: &[u8]) -> Result<(), Error> { + pub fn set_w1(&mut self, w1: &[u8]) -> Result<(), Error> { self.w1 = p256::Scalar::from_repr(*elliptic_curve::generic_array::GenericArray::from_slice(w1)) .unwrap(); @@ -148,12 +149,13 @@ impl CryptoSpake2 for CryptoRustCrypto { #[allow(non_snake_case)] #[allow(dead_code)] - fn set_L(&mut self, l: &[u8]) -> Result<(), Error> { + pub fn set_L(&mut self, l: &[u8]) -> Result<(), Error> { self.L = p256::EncodedPoint::from_bytes(l).unwrap(); Ok(()) } - fn set_L_from_w1s(&mut self, w1s: &[u8]) -> Result<(), Error> { + #[allow(non_snake_case)] + 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 @@ -163,14 +165,14 @@ impl CryptoSpake2 for CryptoRustCrypto { } #[allow(non_snake_case)] - fn get_pB(&mut self, pB: &mut [u8]) -> Result<(), Error> { + 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 // - Y = y*P + w0*N // - pB = Y - let mut rng = rand::thread_rng(); - self.xy = p256::Scalar::random(&mut rng); + let mut rand = RandRngCore(rand); + self.xy = p256::Scalar::random(&mut rand); let P = p256::AffinePoint::GENERATOR; let N = p256::AffinePoint::from_encoded_point(&self.N).unwrap(); @@ -182,7 +184,7 @@ impl CryptoSpake2 for CryptoRustCrypto { } #[allow(non_snake_case)] - fn get_TT_as_verifier( + pub fn get_TT_as_verifier( &mut self, context: &[u8], pA: &[u8], @@ -222,9 +224,7 @@ impl CryptoSpake2 for CryptoRustCrypto { Ok(()) } -} -impl CryptoRustCrypto { fn add_to_tt(tt: &mut sha2::Sha256, buf: &[u8]) -> Result<(), Error> { tt.update((buf.len() as u64).to_le_bytes()); if !buf.is_empty() { @@ -266,11 +266,11 @@ impl CryptoRustCrypto { let mut tmp = x * w0; let N_neg = N.neg(); - let Z = CryptoRustCrypto::do_add_mul(Y, x, N_neg, tmp)?; + let Z = Self::do_add_mul(Y, x, N_neg, tmp)?; // Cofactor for P256 is 1, so that is a No-Op tmp = w1 * w0; - let V = CryptoRustCrypto::do_add_mul(Y, w1, N_neg, tmp)?; + let V = Self::do_add_mul(Y, w1, N_neg, tmp)?; Ok((Z, V)) } @@ -297,27 +297,55 @@ impl CryptoRustCrypto { let tmp = y * w0; let M_neg = M.neg(); - let Z = CryptoRustCrypto::do_add_mul(X, y, M_neg, tmp)?; + let Z = Self::do_add_mul(X, y, M_neg, tmp)?; // Cofactor for P256 is 1, so that is a No-Op let V = (L * y).to_encoded_point(false); Ok((Z, V)) } } +pub struct RandRngCore(pub Rand); + +impl RngCore for RandRngCore { + fn next_u32(&mut self) -> u32 { + let mut buf = [0; 4]; + self.fill_bytes(&mut buf); + + u32::from_be_bytes(buf) + } + + fn next_u64(&mut self) -> u64 { + let mut buf = [0; 8]; + self.fill_bytes(&mut buf); + + u64::from_be_bytes(buf) + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + (self.0)(dest); + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { + self.fill_bytes(dest); + Ok(()) + } +} + +impl CryptoRng for RandRngCore {} + #[cfg(test)] mod tests { use super::*; use elliptic_curve::sec1::FromEncodedPoint; - use crate::secure_channel::crypto::CryptoSpake2; use crate::secure_channel::spake2p_test_vectors::test_vectors::*; #[test] #[allow(non_snake_case)] fn test_get_X() { for t in RFC_T { - let mut c = CryptoRustCrypto::new().unwrap(); + let mut c = CryptoSpake2::new().unwrap(); let x = p256::Scalar::from_repr( *elliptic_curve::generic_array::GenericArray::from_slice(&t.x), ) @@ -325,7 +353,7 @@ mod tests { c.set_w0(&t.w0).unwrap(); let P = p256::AffinePoint::GENERATOR; let M = p256::AffinePoint::from_encoded_point(&c.M).unwrap(); - let r: p256::EncodedPoint = CryptoRustCrypto::do_add_mul(P, x, M, c.w0).unwrap(); + let r: p256::EncodedPoint = CryptoSpake2::do_add_mul(P, x, M, c.w0).unwrap(); assert_eq!(&t.X, r.as_bytes()); } } @@ -334,7 +362,7 @@ mod tests { #[allow(non_snake_case)] fn test_get_Y() { for t in RFC_T { - let mut c = CryptoRustCrypto::new().unwrap(); + let mut c = CryptoSpake2::new().unwrap(); let y = p256::Scalar::from_repr( *elliptic_curve::generic_array::GenericArray::from_slice(&t.y), ) @@ -342,7 +370,7 @@ mod tests { c.set_w0(&t.w0).unwrap(); let P = p256::AffinePoint::GENERATOR; let N = p256::AffinePoint::from_encoded_point(&c.N).unwrap(); - let r = CryptoRustCrypto::do_add_mul(P, y, N, c.w0).unwrap(); + let r = CryptoSpake2::do_add_mul(P, y, N, c.w0).unwrap(); assert_eq!(&t.Y, r.as_bytes()); } } @@ -351,7 +379,7 @@ mod tests { #[allow(non_snake_case)] fn test_get_ZV_as_prover() { for t in RFC_T { - let mut c = CryptoRustCrypto::new().unwrap(); + let mut c = CryptoSpake2::new().unwrap(); let x = p256::Scalar::from_repr( *elliptic_curve::generic_array::GenericArray::from_slice(&t.x), ) @@ -361,7 +389,7 @@ mod tests { let Y = p256::EncodedPoint::from_bytes(t.Y).unwrap(); let Y = p256::AffinePoint::from_encoded_point(&Y).unwrap(); let N = p256::AffinePoint::from_encoded_point(&c.N).unwrap(); - let (Z, V) = CryptoRustCrypto::get_ZV_as_prover(c.w0, c.w1, N, Y, x).unwrap(); + let (Z, V) = CryptoSpake2::get_ZV_as_prover(c.w0, c.w1, N, Y, x).unwrap(); assert_eq!(&t.Z, Z.as_bytes()); assert_eq!(&t.V, V.as_bytes()); @@ -372,7 +400,7 @@ mod tests { #[allow(non_snake_case)] fn test_get_ZV_as_verifier() { for t in RFC_T { - let mut c = CryptoRustCrypto::new().unwrap(); + let mut c = CryptoSpake2::new().unwrap(); let y = p256::Scalar::from_repr( *elliptic_curve::generic_array::GenericArray::from_slice(&t.y), ) @@ -383,7 +411,7 @@ mod tests { let L = p256::EncodedPoint::from_bytes(t.L).unwrap(); let L = p256::AffinePoint::from_encoded_point(&L).unwrap(); let M = p256::AffinePoint::from_encoded_point(&c.M).unwrap(); - let (Z, V) = CryptoRustCrypto::get_ZV_as_verifier(c.w0, L, M, X, y).unwrap(); + let (Z, V) = CryptoSpake2::get_ZV_as_verifier(c.w0, L, M, X, y).unwrap(); assert_eq!(&t.Z, Z.as_bytes()); assert_eq!(&t.V, V.as_bytes()); diff --git a/matter/src/secure_channel/pake.rs b/matter/src/secure_channel/pake.rs index 84c5ba0..cd0ffaf 100644 --- a/matter/src/secure_channel/pake.rs +++ b/matter/src/secure_channel/pake.rs @@ -282,7 +282,7 @@ impl Pake { let mut pB: [u8; 65] = [0; 65]; let mut cB: [u8; 32] = [0; 32]; sd.spake2p.start_verifier(&self.verifier)?; - sd.spake2p.handle_pA(pA, &mut pB, &mut cB)?; + sd.spake2p.handle_pA(pA, &mut pB, &mut cB, self.rand)?; let mut tw = TLVWriter::new(ctx.tx.get_writebuf()?); let resp = Pake1Resp { diff --git a/matter/src/secure_channel/spake2p.rs b/matter/src/secure_channel/spake2p.rs index 9be2d4d..1ee00b6 100644 --- a/matter/src/secure_channel/spake2p.rs +++ b/matter/src/secure_channel/spake2p.rs @@ -196,13 +196,19 @@ impl Spake2P { } #[allow(non_snake_case)] - pub fn handle_pA(&mut self, pA: &[u8], pB: &mut [u8], cB: &mut [u8]) -> Result<(), Error> { + pub fn handle_pA( + &mut self, + pA: &[u8], + pB: &mut [u8], + cB: &mut [u8], + rand: Rand, + ) -> Result<(), Error> { if self.mode != Spake2Mode::Verifier(Spake2VerifierState::Init) { Err(ErrorCode::InvalidState)?; } if let Some(crypto_spake2) = &mut self.crypto_spake2 { - crypto_spake2.get_pB(pB)?; + crypto_spake2.get_pB(pB, rand)?; if let Some(context) = self.context.take() { let mut hash = [0u8; crypto::SHA256_HASH_LEN_BYTES]; context.finish(&mut hash)?; diff --git a/matter/src/transport/network.rs b/matter/src/transport/network.rs index 6cda9bc..e03658b 100644 --- a/matter/src/transport/network.rs +++ b/matter/src/transport/network.rs @@ -17,9 +17,9 @@ use core::fmt::{Debug, Display}; #[cfg(not(feature = "std"))] -use no_std_net::{IpAddr, Ipv4Addr, SocketAddr}; +pub use no_std_net::{IpAddr, Ipv4Addr, SocketAddr}; #[cfg(feature = "std")] -use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +pub use std::net::{IpAddr, Ipv4Addr, SocketAddr}; #[derive(PartialEq, Copy, Clone)] pub enum Address {